├── README.md ├── authentication_server.py ├── blockchain_server.py ├── mining_part.py └── users_part.py /README.md: -------------------------------------------------------------------------------- 1 | # Blockchain Project 2 | Blockchain server, mining server and proof-of-work via python power 3 | 4 | ![alt tag](https://emreovunc.com/projects/Blockchain-Project.png) 5 | 6 | # Aims and Goals 7 | The purpose of this project is to make an open-source Blockchain project and to learn this technology. This blockchain infrastructure can fit the project you want. The project includes important cryptological issues such as public and private keys and changes, SSL / TLS issues. At the same time, multiprocessing and multithreading issues are mentioned in the mining parts. 8 | 9 | # Blockchain 10 | Blockchain technology would help in verifying the integrity of patient data shared across different organizations, create immutable audit trails for data governing health care business processes, and maintain the integrity of data collected in clinical health trials. Blockchains can increase security on three fronts: blocking identity theft, preventing data tampering, and stopping Denial of Service attacks. 11 | 12 | Blockchain is more about guaranteeing the integrity of data rather than keeping data private, it’s not likely to reduce data breaches, but it could prevent — or in some cases, eliminate — tampering types of attack. 13 | 14 | Public Key Infrastructure (PKI) is a popular form of public key cryptography that secures emails, messaging apps, websites, and other forms of communication. However because most implementations of PKI rely on centralized, trusted third party Certificate Authorities (CA) to issue, revoke, and store key pairs for every participant, hackers can compromise them to spoof user identities and crack encrypted communications. 15 | 16 | # MIT License 17 | 18 | Copyright (c) [2019] [EmreOvunc] 19 | 20 | Permission is hereby granted, free of charge, to any person obtaining a copy 21 | of this software and associated documentation files (the "Software"), to deal 22 | in the Software without restriction, including without limitation the rights 23 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 24 | copies of the Software, and to permit persons to whom the Software is 25 | furnished to do so, subject to the following conditions: 26 | 27 | The above copyright notice and this permission notice shall be included in all 28 | copies or substantial portions of the Software. 29 | 30 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 31 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 32 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 33 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 34 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 35 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 36 | SOFTWARE. 37 | -------------------------------------------------------------------------------- /authentication_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | ################################################ 4 | # EMRE OVUNC # 5 | ################################################ 6 | # info@emreovunc.com # 7 | ################################################ 8 | # AUTHENTICATION SERVER # 9 | ################################################ 10 | 11 | import ssl 12 | from time import sleep 13 | from json import dumps 14 | from json import JSONEncoder 15 | from uuid import uuid1 16 | from pickle import dumps as d0 17 | from socket import socket 18 | from socket import AF_INET 19 | from socket import SOL_SOCKET 20 | from socket import SOCK_STREAM 21 | from socket import SO_REUSEADDR 22 | from threading import Thread 23 | from subprocess import PIPE 24 | from subprocess import Popen 25 | from Crypto.Hash import SHA512 26 | from cryptography.hazmat.backends import default_backend 27 | from cryptography.hazmat.primitives import hashes 28 | from cryptography.hazmat.primitives import serialization 29 | from cryptography.hazmat.primitives.ciphers import modes 30 | from cryptography.hazmat.primitives.ciphers import Cipher 31 | from cryptography.hazmat.primitives.ciphers import algorithms 32 | from cryptography.hazmat.primitives.kdf.hkdf import HKDF 33 | from cryptography.hazmat.primitives.asymmetric import ec 34 | 35 | utf_type = 'utf-8' 36 | 37 | number_servers = 4 38 | blockCodes = [] 39 | binding_address = 'X' 40 | port_number = 55555 41 | 42 | # Values 43 | chainUUID = "" 44 | key_storage = [] 45 | 46 | 47 | # Generate 2048-bits prime number 48 | def generate_blockcodes(): 49 | if len(blockCodes) == 13: 50 | return True 51 | prime_proc = Popen(['openssl prime -generate -bits 2048'], stdout=PIPE, shell=True) 52 | (out, err) = prime_proc.communicate() 53 | generated_code = out.decode(utf_type) 54 | for codes in blockCodes: 55 | if codes == generated_code: 56 | generate_blockcodes() 57 | blockCodes.append(generated_code) 58 | generate_blockcodes() 59 | 60 | 61 | # Encoder class for mongodb blocks 62 | class Encoder(JSONEncoder): 63 | def default(self, obj): 64 | if isinstance(obj, ObjectId): 65 | return str(obj) 66 | else: 67 | return obj 68 | 69 | 70 | # Save important informations 71 | def send_others_public(peer_public, peer_ip, shared_pairs): 72 | global key_storage 73 | changed = 0 74 | # Update values 75 | for keys in key_storage: 76 | if keys[1] == peer_ip: 77 | keys = (peer_public, peer_ip, shared_pairs) 78 | changed = 1 79 | break 80 | 81 | # Add values 82 | if changed == 0: 83 | key_storage.append((peer_public, peer_ip, shared_pairs)) 84 | 85 | # Send values 86 | for keys in key_storage: 87 | if keys[1] != peer_ip: 88 | connect(keys[1], aes_encryption_func(derivation_keys(keys[2]), 89 | keys[2], 90 | (peer_public + peer_ip.encode(utf_type)))) 91 | 92 | connect(peer_ip, aes_encryption_func(derivation_keys(shared_pairs), 93 | shared_pairs, 94 | (keys[0] + keys[1].encode(utf_type)))) 95 | 96 | 97 | # CLIENT SIDE 98 | # Send any block to others 99 | def connect(HOST, message): 100 | # Socket informations 101 | try: 102 | mySocket = socket(AF_INET, SOCK_STREAM) 103 | mySocket.settimeout(2) 104 | context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH) 105 | context.check_hostname = False 106 | context.load_cert_chain('selfsigned.cert', 'selfsigned.key') 107 | context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 108 | conn = context.wrap_socket(mySocket) 109 | conn.connect((HOST, port_number)) 110 | 111 | # Sending bytes data.. 112 | if type(message) == bytes: 113 | conn.send(message) 114 | 115 | # '.obj' in str(type(message)) 116 | else: 117 | try: 118 | msg = dumps(message.__dict__) 119 | 120 | except: 121 | try: 122 | msg = dumps(message.__dict__, cls=Encoder) 123 | 124 | except: 125 | msg = message 126 | 127 | try: 128 | conn.send(d0(msg.encode("ISO-8859-1"))) 129 | except: 130 | 131 | try: 132 | conn.send(msg) 133 | except: 134 | return False 135 | 136 | conn.close() 137 | return True 138 | 139 | except ConnectionRefusedError: 140 | return False 141 | 142 | except: 143 | return False 144 | 145 | 146 | # SERVER SIDE 147 | # Receive data from the socket 148 | class ClientThread(Thread): 149 | def __init__(self, conn, IP_ADD): 150 | Thread.__init__(self) 151 | self.IP_ADD = IP_ADD 152 | self.conn = conn 153 | 154 | def run(self): 155 | while True: 156 | # Receive bytes 157 | try: 158 | tempBytes = self.conn.recv(4096) 159 | 160 | except: 161 | break 162 | 163 | # Block Reloading.. 164 | try: 165 | # If the public key received 166 | if str(tempBytes.decode(utf_type)).startswith("-----BEGIN PUBLIC KEY-----") and\ 167 | "-----END PUBLIC KEY-----" in str(tempBytes.decode(utf_type)): 168 | 169 | # Get UUID hash 170 | if control_uuid(tempBytes.decode(utf_type).split('-----END PUBLIC KEY-----\n')[1]): 171 | 172 | ecdh_pairs = elliptic_pair() 173 | connect(self.IP_ADD, ecdh_pairs.serialized_public) 174 | sleep(1) 175 | 176 | certificate = tempBytes.decode(utf_type).split(tempBytes.decode(utf_type)[-128:])[0].encode(utf_type) 177 | global chainUUID 178 | shared_pairs = ecdh_pairs.findsharedKEY(deserialize_pubkey(certificate)) 179 | 180 | for index in range(0, len(blockCodes)): 181 | connect(self.IP_ADD, aes_encryption_func(derivation_keys(shared_pairs), 182 | shared_pairs, 183 | blockCodes[index])) 184 | sleep(0.25) 185 | 186 | send_others_public(certificate, self.IP_ADD, shared_pairs) 187 | chainUUID = 0 188 | 189 | break 190 | 191 | else: 192 | break 193 | 194 | except: 195 | break 196 | 197 | 198 | # UUID controlling.. 199 | def control_uuid(peer_uuid): 200 | global chainUUID 201 | if peer_uuid == SHA512.new(str(chainUUID).encode(utf_type)).hexdigest(): 202 | return True 203 | return False 204 | 205 | 206 | # Listen all connections 207 | def Conn(): 208 | tcpServer = socket(AF_INET, SOCK_STREAM) 209 | tcpServer.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 210 | tcpServer.bind((binding_address, port_number)) 211 | tcpServer.listen(200) 212 | 213 | context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH) 214 | context.load_cert_chain('selfsigned.cert', 'selfsigned.key') 215 | context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 216 | context.set_ciphers('EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH') 217 | 218 | threads = [] 219 | 220 | while True: 221 | 222 | try: 223 | (conn, (IP_ADD, port_number_ADD)) = tcpServer.accept() 224 | conn = context.wrap_socket(conn, server_side=True) 225 | newthread = ClientThread(conn, IP_ADD) 226 | newthread.start() 227 | threads.append(newthread) 228 | 229 | except ssl.SSLError: 230 | debug('Sender does NOT use SSL..!') 231 | 232 | except: 233 | pass 234 | 235 | try: 236 | if not threads[0].is_alive(): 237 | del threads[0] 238 | except: 239 | pass 240 | 241 | for t in threads: 242 | t.join() 243 | 244 | 245 | # UUID Generator for new comers 246 | def uuid_generator(): 247 | global chainUUID 248 | chainUUID = uuid1() 249 | 250 | file = open('/var/www/html/code.txt', 'w') 251 | file.write(str(chainUUID)) 252 | file.close() 253 | 254 | return chainUUID 255 | 256 | 257 | # Elliptic curve key-pairs 258 | class elliptic_pair: 259 | def __init__(self): 260 | # Generate a private key for use in the exchange. 261 | self.private_key = ec.generate_private_key(ec.SECT571K1, default_backend()) 262 | self.public_key = self.private_key.public_key() 263 | 264 | # Serialization of Public Key 265 | self.serialized_public = self.public_key.public_bytes( 266 | encoding = serialization.Encoding.PEM, 267 | format = serialization.PublicFormat.SubjectPublicKeyInfo) 268 | 269 | # To find shared secret using user's private and other's public 270 | def findsharedKEY(self, peer_public): 271 | shared_key = self.private_key.exchange(ec.ECDH(), peer_public) 272 | return shared_key 273 | 274 | # Serialize and save private key 275 | def __serialize_private(self): 276 | __serialized_private = self.private_key.private_bytes( 277 | encoding = serialization.Encoding.PEM, 278 | format = serialization.PrivateFormat.PKCS8, 279 | encryption_algorithm = serialization.BestAvailableEncryption(bytes(blockCodes[0]))) 280 | 281 | # Signing the message 282 | def sign_message(self, message): 283 | message = message.encode(utf_type) 284 | sign = self.private_key.sign(message, ec.ECDSA(hashes.SHA256())) 285 | return sign 286 | 287 | @staticmethod 288 | # Verifying the message 289 | def verify_message(public_key, message, sign): 290 | message = message.encode(utf_type) 291 | return public_key.verify(sign, message, ec.ECDSA(hashes.SHA256())) 292 | 293 | 294 | # De-serialization of Public Key 295 | def deserialize_pubkey(peer_public): 296 | loaded_public_key = serialization.load_pem_public_key( 297 | peer_public, 298 | backend = default_backend()) 299 | return loaded_public_key 300 | 301 | 302 | # HMAC-based Extract and Expand Key Derivation Function 303 | def derivation_keys(shared_key): 304 | if not type(shared_key) == bytes: 305 | shared_key = shared_key.encode(utf_type) 306 | hkdf = HKDF( 307 | algorithm = hashes.SHA256() , 308 | length = 32 , 309 | salt = shared_key[16:32] , 310 | info = shared_key[:16] , 311 | backend = default_backend()) 312 | 313 | keyDerived = hkdf.derive(shared_key[16:]) 314 | return keyDerived 315 | 316 | 317 | # AES Encryption Part 318 | def aes_encryption_func(keyDerived, shared_key, message): 319 | if not type(message) == bytes: 320 | message = message.encode(utf_type) 321 | if not type(shared_key) == bytes: 322 | shared_key = shared_key.encode(utf_type) 323 | if not type(keyDerived) == bytes: 324 | keyDerived = keyDerived.encode(utf_type) 325 | length = 16 - (len(message) % 16) 326 | message += bytes([length]) * length 327 | backend = default_backend() 328 | key = keyDerived 329 | iv = shared_key[:16] 330 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 331 | encryptor = cipher.encryptor() 332 | encrypted = encryptor.update(message) + encryptor.finalize() 333 | return encrypted 334 | 335 | 336 | # AES Decryption Part 337 | def aes_decryption_func(keyDerived, shared_key, message): 338 | if not type(message) == bytes: 339 | message = message.encode(utf_type) 340 | if not type(shared_key) == bytes: 341 | shared_key = shared_key.encode(utf_type) 342 | if not type(keyDerived) == bytes: 343 | keyDerived = keyDerived.encode(utf_type) 344 | backend = default_backend() 345 | key = keyDerived 346 | iv = shared_key[:16] 347 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 348 | decryptor = cipher.decryptor() 349 | dt = decryptor.update(message) + decryptor.finalize() 350 | decrypted = dt[:-dt[-1]].decode(utf_type) 351 | return decrypted 352 | 353 | 354 | def generate_uuids(): 355 | uuid_generator() 356 | global chainUUID 357 | time = 90 358 | while True: 359 | if time <= 0: 360 | generate_uuids() 361 | 362 | if chainUUID == 0: 363 | generate_uuids() 364 | 365 | sleep(1) 366 | time -= 1 367 | 368 | 369 | def main(): 370 | generate_blockcodes() 371 | 372 | # Create a listening server 373 | listenConn = Thread(target=Conn, ) 374 | listenConn.start() 375 | sleep(0.5) 376 | 377 | generateuuid = Thread(target=generate_uuids, ) 378 | generateuuid.start() 379 | sleep(0.5) 380 | 381 | main() 382 | -------------------------------------------------------------------------------- /blockchain_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | ################################################ 4 | # EMRE OVUNC # 5 | ################################################ 6 | # info@emreovunc.com # 7 | ################################################ 8 | # BLOCKCHAIN SERVER # 9 | ################################################ 10 | 11 | import ssl 12 | from os import system 13 | from sys import exit 14 | from time import sleep 15 | from json import dumps 16 | from json import loads 17 | from json import JSONEncoder 18 | from queue import Queue 19 | from pickle import dumps as d0 20 | from pickle import loads as l0 21 | from random import choice 22 | from random import randint 23 | from socket import socket 24 | from socket import AF_INET 25 | from socket import SOL_SOCKET 26 | from socket import SOCK_STREAM 27 | from socket import SO_REUSEADDR 28 | from base64 import b64encode 29 | from base64 import b64decode 30 | from string import digits 31 | from string import ascii_lowercase 32 | from string import ascii_uppercase 33 | from os.path import isfile 34 | from logging import info 35 | from logging import debug 36 | from logging import DEBUG 37 | from logging import warning 38 | from logging import basicConfig 39 | from pymongo import MongoClient 40 | from threading import Lock 41 | from threading import Thread 42 | from subprocess import PIPE 43 | from subprocess import Popen 44 | from Crypto.Hash import SHA512 45 | from bson.objectid import ObjectId 46 | from multiprocessing import Process 47 | from multiprocessing import Manager 48 | from cryptography.hazmat.backends import default_backend 49 | from cryptography.hazmat.primitives import hashes 50 | from cryptography.hazmat.primitives import serialization 51 | from cryptography.hazmat.primitives.ciphers import modes 52 | from cryptography.hazmat.primitives.ciphers import Cipher 53 | from cryptography.hazmat.primitives.ciphers import algorithms 54 | from cryptography.hazmat.primitives.kdf.hkdf import HKDF 55 | from cryptography.hazmat.primitives.asymmetric import ec 56 | 57 | # Logging configuration 58 | basicConfig(filename = 'eo_blockchain.log', 59 | level = DEBUG, 60 | format = '%(asctime)s : %(levelname)s : %(message)s', 61 | datefmt = '%m/%d/%Y %I:%M:%S %p') 62 | 63 | # Default(s) 64 | flag_who = 0 65 | 66 | # Confirmation queue 67 | queue_conf = Queue(maxsize=500) 68 | queue_verify = Queue(maxsize=500) 69 | queue_miner = Queue(maxsize=500) 70 | queue_chain = Queue(maxsize=500) 71 | queue_user = Queue(maxsize=500) 72 | queue_verifytimer = Queue(maxsize=500) 73 | queue_conftimer = Queue(maxsize=500) 74 | 75 | # Queue timeout 30 seconds for each item 76 | timeout_queue = 30 77 | 78 | # Temp. Queues 79 | queue_temp1 = Queue(maxsize=500) 80 | queue_temp2 = Queue(maxsize=500) 81 | 82 | # Connection informations 83 | binding_address = "X" 84 | chain_hosts = ["Y"] 85 | miner_hosts = ['Z'] 86 | auth_host = 'T' 87 | port_number = 55555 88 | 89 | # Multi-threading 90 | lock_miner = Lock() 91 | lock_user = Lock() 92 | lock_chain = Lock() 93 | 94 | # blockID & prevHash 95 | blockid_curr = 0 96 | prevhash_curr = 0 97 | phash_curr = 0 98 | last_idcurr = 0 99 | 100 | # MongoDB database name 101 | mongodbName = 'eovunc_Blockchain' 102 | 103 | # Encoding & Decoding type 104 | utf_type = 'utf-8' 105 | 106 | # Multi-processing 107 | manager = Manager() 108 | queue_block_who = manager.Queue(maxsize=500) 109 | 110 | # ECDH Pairs 111 | storage_pub = [] 112 | 113 | # Values 114 | chainUUID = "" 115 | uuid_path = 'uuid.txt' 116 | 117 | # Connect MongoDB 118 | try: 119 | client = MongoClient('localhost', 27017) 120 | db = client.eovunc_Blockchain 121 | except: 122 | warning('MongoDB is not connected!!!') 123 | 124 | # Block Communication Codes 125 | codes_of_block = [] 126 | 127 | # 0 for Block is NoK 128 | # 1 for Block is OK 129 | # 2 for Hash is NoK 130 | # 3 for Hash is OK 131 | # 4 for lastBlock is NoK 132 | # 5 for lastBlock is OK 133 | # 6 for lastBlock Request 134 | # 7 for Database add 135 | # 8 for User NoK 136 | # 9 for User OK 137 | # 10 for User Request 138 | # 11 for Block values request 139 | # 12 for Send your blocks 140 | 141 | # Block headers 142 | header_of_block = 143 | [ 144 | 'senderID' , 'receiverID', 'message' , 'timestamp', 145 | 'digitalSignature', 'verKey' , 'prevHash' , '_id' , 146 | 'hash' , 'who' , 'totalHash', 'blockID' , 147 | 'nonce' 148 | ] 149 | 150 | # Block.ok and NoK objects 151 | blockCalc = [] 152 | 153 | 154 | # Block ok and NoK values calculation 155 | class block_calc: 156 | def __init__(self, hash, ok, NoK, IP): 157 | info('block_calc object is created.') 158 | self.hash = hash 159 | self.ok = ok 160 | self.NoK = NoK 161 | self.IP = [] 162 | self.IP.append(IP) 163 | 164 | 165 | # Queue Function for putting 166 | def put_queue(q, data): 167 | if q == queue_conf: 168 | info('Data is putting in the queue [Confirmation Queue]') 169 | 170 | elif q == queue_verify: 171 | info('Data is putting in the queue [Verifying Queue]' ) 172 | 173 | elif q == queue_user: 174 | info('Data is putting in the queue [User Queue]' ) 175 | 176 | elif q == queue_miner: 177 | info('Data is putting in the queue [Miner Queue]' ) 178 | 179 | elif q == queue_chain: 180 | info('Data is putting in the queue [Chain Queue]' ) 181 | 182 | else: 183 | info('Data is putting in the queue [Temp. Queue(s)]' ) 184 | 185 | try: 186 | q.put(data, timeout=timeout_queue) 187 | except: 188 | get_from_queue(q) 189 | try: 190 | q.put(data, timeout=timeout_queue) 191 | except: 192 | pass 193 | 194 | 195 | # Queue Function for getting 196 | def get_from_queue(q): 197 | if q == queue_conf: 198 | info('Data is getting from the [Confirmation Queue]' ) 199 | 200 | elif q == queue_verify: 201 | info('Data is getting from the [Verifying Queue]' ) 202 | 203 | elif q == queue_user: 204 | info('Data is getting in the queue [User Queue]' ) 205 | 206 | elif q == queue_miner: 207 | info('Data is getting in the queue [Miner Queue]' ) 208 | 209 | elif q == queue_chain: 210 | info('Data is getting in the queue [Chain Queue]' ) 211 | 212 | else: 213 | info('Data is getting from the [Temp. Queue(s)]' ) 214 | 215 | try: 216 | if int(q.qsize()) != 0: 217 | return q.get() 218 | except: 219 | return 0 220 | 221 | 222 | # Queue Function for queue size 223 | def get_size_queue(q): 224 | if q == queue_conf: 225 | info('Get Queue size [Confirmation Queue]' ) 226 | 227 | elif q == queue_verify: 228 | info('Get Queue size [Verifying Queue]' ) 229 | 230 | elif q == queue_user: 231 | info('Data is putting in the queue [User Queue]' ) 232 | 233 | elif q == queue_miner: 234 | info('Data is putting in the queue [Miner Queue]' ) 235 | 236 | elif q == queue_chain: 237 | info('Data is putting in the queue [Chain Queue]' ) 238 | 239 | else: 240 | info('Get Queue size [Temp. Queue(s)]' ) 241 | 242 | return int(q.qsize()) 243 | 244 | 245 | # Convert hex to decimal 246 | def conv_mod_10(hex): 247 | if hex == 'a': 248 | return 0 249 | 250 | elif hex == 'b': 251 | return 1 252 | 253 | elif hex == 'c': 254 | return 2 255 | 256 | elif hex == 'd': 257 | return 3 258 | 259 | elif hex == 'e': 260 | return 4 261 | 262 | elif hex == 'f': 263 | return 5 264 | 265 | else: 266 | return hex 267 | 268 | 269 | def conv_mod_16(nmbr): 270 | if int(nmbr) == 0: 271 | return 'a' 272 | 273 | elif int(nmbr) == 1: 274 | return 'b' 275 | 276 | elif int(nmbr) == 2: 277 | return 'c' 278 | 279 | elif int(nmbr) == 3: 280 | return 'd' 281 | 282 | elif int(nmbr) == 4: 283 | return 'e' 284 | 285 | elif int(nmbr) == 5: 286 | return 'f' 287 | 288 | else: 289 | return nmbr 290 | 291 | 292 | # Convert parts to decimal 293 | def conv_10(part): 294 | # If part has one string 295 | if len(str(part)) == 1: 296 | part = conv_mod_10(part) 297 | 298 | # If part has more strings 299 | elif len(str(part)) == 2: 300 | try: 301 | part1 = int(part[0]) 302 | except: 303 | part1 = conv_mod_10(part[0]) 304 | 305 | try: 306 | part2 = int(part[1]) 307 | except: 308 | part2 = conv_mod_10(part[1]) 309 | 310 | part = str(part1) + str(part2) 311 | 312 | # If part becomes an ERROR 313 | else: 314 | debug('conv_10() string ERROR!') 315 | 316 | return int(part) 317 | 318 | 319 | # Convert parts to hexadecimal 320 | def conv_16(part): 321 | addPart = [] 322 | 323 | for parts in part: 324 | # If parts have one digit 325 | if len(str(parts)) == 1: 326 | 327 | chance = randint(0, 1) 328 | if chance == 1: 329 | addPart.append('0' + str(conv_mod_16(parts))) 330 | 331 | else: 332 | addPart.append('0' + str(parts)) 333 | 334 | # If parts have two digits. 335 | elif len(str(parts)) == 2: 336 | parts = str(parts) 337 | 338 | chance = randint(0, 1) 339 | if chance == 1: 340 | x = conv_mod_16(parts[0]) 341 | 342 | else: 343 | x = parts[0] 344 | 345 | chance = randint(0, 1) 346 | if chance == 1: 347 | y = conv_mod_16(parts[1]) 348 | 349 | else: 350 | y = parts[1] 351 | 352 | addPart.append(str(x) + str(y)) 353 | 354 | # If parts have three digits 355 | else: 356 | parts = str(parts) 357 | 358 | chance = randint(0, 1) 359 | if chance == 1: 360 | x = conv_mod_16(parts[0]) 361 | 362 | else: 363 | x = parts[0] 364 | 365 | chance = randint(0, 1) 366 | if chance == 1: 367 | y = conv_mod_16(parts[1]) 368 | 369 | else: 370 | y = parts[0] 371 | 372 | chance = randint(0, 1) 373 | if chance == 1: 374 | z = conv_mod_16(parts[2]) 375 | 376 | else: 377 | z = parts[2] 378 | 379 | addPart.append(str(x) + str(y) + str(z)) 380 | 381 | return addPart 382 | 383 | 384 | # Find and return block_calc object 385 | def find_obj(blockHash, IPAdd): 386 | for calcs in blockCalc: 387 | if calcs.hash == blockHash: 388 | info('Calc0bj already created.!') 389 | return calcs, 1 390 | 391 | info('Calc0bj is appending...') 392 | blockCalc.append(block_calc(blockHash, 0, 0, IPAdd)) 393 | return blockCalc[-1], 0 394 | 395 | 396 | # Find and remove block_calc object 397 | def remove_obj(blockHash): 398 | info('Calc0bj is deleted!') 399 | for calcs in blockCalc: 400 | if calcs.hash == blockHash: 401 | blockCalc.remove(calcs) 402 | del calcs 403 | break 404 | 405 | 406 | # Identify sender 407 | def detect_block(whoHash): 408 | info('Identifying sender..') 409 | # Get the iteration number 410 | groups = [whoHash[-1]] 411 | 412 | # Split the headers 413 | for splitter in range(0, 11): 414 | if splitter % 2 == 0: 415 | groups.append(whoHash[splitter] + whoHash[splitter + 1]) 416 | 417 | # Get correct hash length 418 | whoHash = whoHash[12:-1] 419 | 420 | # Shifting hash 421 | if int(groups[0]) != 0: 422 | for times in range(0, int(groups[0])): 423 | sftHash = '' 424 | temp = whoHash[127] 425 | 426 | for item in range(0, 128): 427 | sftHash += whoHash[item] 428 | 429 | sftHash = temp + sftHash 430 | whoHash = sftHash 431 | newHash = whoHash[:-1] 432 | 433 | else: 434 | newHash = whoHash 435 | 436 | # Convert groups elements.. 437 | for gRange in range(1, len(groups)): 438 | groups[gRange] = conv_10(groups[gRange]) 439 | 440 | # Check hash ... 441 | if str(newHash).startswith('0'): 442 | 443 | # USER PART 444 | # Check hash by using groups rules - PART I 445 | if int(conv_mod_10(newHash[groups[-1]])) == int(conv_mod_10(newHash[groups[-2]])): 446 | 447 | # Check hash by using groups rules - PART II 448 | if int(conv_mod_10(newHash[groups[-3]])) == int(conv_mod_10(newHash[groups[-4]])): 449 | 450 | # Check hash by using groups rules - PART III 451 | if (int(conv_mod_10(newHash[groups[-1]])) + int(conv_mod_10(newHash[groups[-3]]))) % 10 == \ 452 | int(conv_mod_10(newHash[groups[-5]])): 453 | # Correct Hash 454 | # Comes from user part 455 | return 1 456 | 457 | else: 458 | # BLOCKCHAIN SERVER PART 459 | # Check hash by using groups rules - PART I 460 | if int(conv_mod_10(newHash[groups[-1]])) == int(conv_mod_10(newHash[groups[-3]])): 461 | 462 | # Check hash by using groups rules - PART II 463 | if (int(conv_mod_10(newHash[groups[-2]])) + int(conv_mod_10(newHash[groups[-4]]))) % 10 == \ 464 | int(conv_mod_10(newHash[groups[-5]])): 465 | 466 | # Check hash by using groups rules - PART III 467 | if (int(conv_mod_10(newHash[groups[-1]])) + int(conv_mod_10(newHash[groups[-3]]))) % 10 == \ 468 | int(conv_mod_10(newHash[groups[-5]])): 469 | # Correct Hash 470 | # Comes from blockchain part 471 | return 3 472 | 473 | # MINING PART 474 | else: 475 | # Check hash by using groups rules - PART I 476 | if (int(conv_mod_10(newHash[groups[-1]])) + int(conv_mod_10(newHash[groups[-2]]))) % 10 == \ 477 | int(conv_mod_10(newHash[groups[-3]])): 478 | 479 | # Check hash by using groups rules - PART II 480 | if int(conv_mod_10(newHash[groups[-4]])) == int(conv_mod_10(newHash[groups[-5]])): 481 | 482 | # Check hash by using groups rules - PART III 483 | if (int(conv_mod_10(newHash[groups[-1]])) + int(conv_mod_10(newHash[groups[-3]]))) % 10 == \ 484 | int(conv_mod_10(newHash[groups[-5]])): 485 | # Correct Hash 486 | # Comes from mining part 487 | return 2 488 | 489 | debug('Incorrect Hash ..!') 490 | return 0 491 | 492 | 493 | # Create a merkle hash and return ROOT 494 | def main_block(Block, req): 495 | global blockid_curr 496 | 497 | merkle = '' 498 | 499 | if req == 1: 500 | newblockID = SHA512.new(str(Block.blockID).encode(utf_type)).hexdigest() 501 | 502 | elif req == 2: 503 | newblockID = SHA512.new(str(int(blockid_curr) + 1).encode(utf_type)).hexdigest() 504 | 505 | elif req == 3: 506 | newblockID = SHA512.new(str(int(blockid_curr)).encode(utf_type)).hexdigest() 507 | 508 | else: 509 | return 0 510 | 511 | 512 | newsenderID = SHA512.new(str(Block.senderID) .encode(utf_type)) .hexdigest() 513 | newreceiverID = SHA512.new(str(Block.receiverID) .encode(utf_type)) .hexdigest() 514 | newMessage = SHA512.new(str(Block.message) .encode(utf_type)) .hexdigest() 515 | newTimestamp = SHA512.new(str(Block.timestamp) .encode(utf_type)) .hexdigest() 516 | newDS = SHA512.new(str(Block.digitalSignature) .encode(utf_type)) .hexdigest() 517 | newPrevHash = SHA512.new(str(Block.prevHash) .encode(utf_type)) .hexdigest() 518 | 519 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newsenderID) .encode(utf_type)) .hexdigest() 520 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newreceiverID) .encode(utf_type)) .hexdigest() 521 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newMessage) .encode(utf_type)) .hexdigest() 522 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newTimestamp) .encode(utf_type)) .hexdigest() 523 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newDS) .encode(utf_type)) .hexdigest() 524 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newPrevHash) .encode(utf_type)) .hexdigest() 525 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newblockID) .encode(utf_type)) .hexdigest() 526 | root = SHA512.new(str(merkle).encode(utf_type) + str(Block.nonce) .encode(utf_type)) .hexdigest() 527 | 528 | info('Merkle tree created..') 529 | 530 | return root 531 | 532 | 533 | # Check block hash re-calculation 534 | def controlling_hash(Block, blockWho): 535 | info('Starting block hash controls..') 536 | 537 | # Proof of Work control.. 538 | if Block.hash.startswith('000'): 539 | info('Block.hash "00000"') 540 | 541 | for blockcode in codes_of_block: 542 | newCode = SHA512.new(str(blockcode).encode(utf_type)).hexdigest() 543 | 544 | # If calculated hash equals to block hash 545 | if Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 546 | str(newCode).encode(utf_type)).hexdigest(): 547 | info('Blockhash is verified.') 548 | return True 549 | 550 | if blockWho == 3: 551 | 552 | if Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 553 | str(code_block_06).encode(utf_type) + 554 | str(code_block_11).encode(utf_type)).hexdigest(): 555 | return True 556 | 557 | elif Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 558 | str(code_block_01).encode(utf_type) + 559 | str(code_block_03).encode(utf_type)).hexdigest(): 560 | return True 561 | 562 | elif Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 563 | str(code_block_04).encode(utf_type) + 564 | str(code_block_00).encode(utf_type)).hexdigest(): 565 | return True 566 | 567 | elif Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 568 | str(code_block_10).encode(utf_type) + 569 | str(code_block_11).encode(utf_type) + 570 | str(code_block_12).encode(utf_type)).hexdigest(): 571 | return True 572 | 573 | elif Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 574 | str(code_block_12).encode(utf_type)).hexdigest(): 575 | return True 576 | 577 | debug('Blockhash is NOT verified!') 578 | return False 579 | 580 | 581 | # Generate a block_chain hash to set who value 582 | def generate_block_hash(): 583 | while True: 584 | part = [randint(0, 99), randint(0, 99), 585 | randint(0, 99), randint(0, 99), 586 | randint(1, 99), randint(1, 99)] 587 | 588 | if part[0] != part[1] and part[1] != part[2] and part[2] != part[3] and \ 589 | part[3] != part[4] and part[4] != part[5] and part[0] != part[2] and \ 590 | part[0] != part[3] and part[0] != part[4] and part[4] != part[5] and \ 591 | part[1] != part[3] and part[1] != part[4] and part[1] != part[5] and \ 592 | part[2] != part[4] and part[2] != part[5] and part[3] != part[5]: 593 | hexPart = conv_16(part) 594 | 595 | number = randint(0, 128) 596 | n = "" 597 | for iteration in range(0, number): 598 | n = choice(digits) + str(number) + choice(ascii_lowercase) + choice(ascii_uppercase) + n 599 | myHash = SHA512.new(str(n).encode(utf_type)).hexdigest() 600 | newHash = '' 601 | 602 | if myHash.startswith('0'): 603 | try: 604 | item1 = int(myHash[part[0]]) % 10 605 | except ValueError: 606 | item1 = conv_mod_10(myHash[part[0]]) 607 | 608 | try: 609 | item2 = int(myHash[part[1]]) % 10 610 | except ValueError: 611 | item2 = conv_mod_10(myHash[part[1]]) 612 | 613 | try: 614 | item3 = int(myHash[part[2]]) % 10 615 | except ValueError: 616 | item3 = conv_mod_10(myHash[part[2]]) 617 | 618 | if int(item1) != int(item2): 619 | 620 | if int(item1) + int(item2) % 10 != int(item3): 621 | 622 | if int(item1) == int(item3): 623 | 624 | try: 625 | item4 = int(myHash[part[3]]) % 10 626 | except ValueError: 627 | item4 = conv_mod_10(myHash[part[3]]) 628 | 629 | try: 630 | item5 = int(myHash[part[4]]) % 10 631 | except: 632 | item5 = conv_mod_10(myHash[part[4]]) 633 | 634 | if int(item2) + int(item4) % 10 == int(item5): 635 | 636 | if (int(item1) + int(item3)) % 10 == int(item5): 637 | 638 | try: 639 | shifting = int(myHash[part[5]]) % 10 640 | except: 641 | shifting = conv_mod_10(myHash[part[5]]) 642 | 643 | flg = shifting 644 | 645 | if int(shifting) != 0: 646 | 647 | for times in range(0, int(shifting)): 648 | sftHash = '' 649 | temp = myHash[0] 650 | 651 | for item in range(1, int(len(myHash))): 652 | 653 | try: 654 | sftHash += myHash[item] 655 | except IndexError: 656 | pass 657 | 658 | sftHash += temp 659 | myHash = sftHash 660 | newHash = myHash 661 | 662 | for hexs in hexPart: 663 | newHash = hexs + newHash 664 | 665 | return newHash + str(flg) 666 | 667 | else: 668 | 669 | for hexs in hexPart: 670 | myHash = hexs + myHash 671 | 672 | return myHash + str(flg) 673 | 674 | 675 | # Controlling blockchain.blockID and received blockID 676 | def checking_block_id(Block): 677 | info('Starting blockID controls ...') 678 | 679 | try: 680 | # Get block.blockID 681 | calcHash = main_block(Block, 2) 682 | 683 | if str(calcHash) == str(Block.hash): 684 | return True 685 | 686 | elif Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 687 | str(code_block_06).encode(utf_type)).hexdigest() or \ 688 | Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 689 | str(code_block_06).encode(utf_type) + 690 | str(code_block_11).encode(utf_type)).hexdigest() or \ 691 | Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 692 | str(code_block_01).encode(utf_type) + 693 | str(code_block_03).encode(utf_type)).hexdigest() or \ 694 | Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 695 | str(code_block_07).encode(utf_type)).hexdigest() or \ 696 | Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 697 | str(code_block_10).encode(utf_type)).hexdigest(): 698 | 699 | calcHash = main_block(Block, 3) 700 | 701 | if str(calcHash) == str(Block.hash): 702 | return True 703 | 704 | if Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 705 | str(code_block_11).encode(utf_type)).hexdigest(): 706 | return True 707 | 708 | return False 709 | 710 | except: 711 | debug('Control blockID has an ERROR..!') 712 | return False 713 | 714 | 715 | # Verify block header 716 | def checking_block_head(Block): 717 | info('Starting block header controls ...') 718 | 719 | try: 720 | # Get blockheader items 721 | for items in Block.__dict__: 722 | flag = 0 723 | 724 | for heads in header_of_block: 725 | flag += 1 726 | 727 | # If item was found in the header_of_block 728 | if items == heads: 729 | break 730 | 731 | # If blockheader has more items 732 | if flag > 15: 733 | info('Blockheader is INCORRECT!') 734 | return False 735 | 736 | if len(Block.__dict__) == 13: 737 | info('Blockheader is correct.') 738 | return True 739 | 740 | else: 741 | info('Blockheader is INCORRECT!') 742 | return False 743 | 744 | except: 745 | debug('Header has something wrong!') 746 | return False 747 | 748 | 749 | # Elliptic curve key-pairs 750 | class elliptic_pair: 751 | def __init__(self): 752 | # Generate a private key for use in the exchange. 753 | self.private_key = ec.generate_private_key(ec.SECT571K1, default_backend()) 754 | self.public_key = self.private_key.public_key() 755 | 756 | # Serialization of Public Key 757 | self.serialized_public = self.public_key.public_bytes( 758 | encoding = serialization.Encoding.PEM, 759 | format = serialization.PublicFormat.SubjectPublicKeyInfo) 760 | 761 | # To find shared secret using user's private and other's public 762 | def found_shared_secret(self, peer_public): 763 | shared_key = self.private_key.exchange(ec.ECDH(), peer_public) 764 | return shared_key 765 | 766 | # Serialize and save private key 767 | def __serialize_private(self): 768 | __serialized_private = self.private_key.private_bytes( 769 | encoding = serialization.Encoding.PEM, 770 | format = serialization.PrivateFormat.PKCS8, 771 | encryption_algorithm = serialization.BestAvailableEncryption(bytes(codes_of_block[0]))) 772 | 773 | # Signing the message 774 | def messageSign(self, message): 775 | message = message.encode(utf_type) 776 | sign = self.private_key.sign(message, ec.ECDSA(hashes.SHA256())) 777 | return sign 778 | 779 | @staticmethod 780 | # Verifying the message 781 | def verifyMSG(public_key, message, sign): 782 | try: 783 | sign = b64decode(sign).encode("ISO-8859-1") 784 | except: 785 | sign = b64decode(sign) 786 | message = message.encode(utf_type) 787 | return public_key.verify(sign, message, ec.ECDSA(hashes.SHA256())) 788 | 789 | 790 | # De-serialization of Public Key 791 | def deserialize_pubkey(peer_public): 792 | loaded_public_key = serialization.load_pem_public_key( 793 | peer_public, 794 | backend = default_backend()) 795 | return loaded_public_key 796 | 797 | 798 | # HMAC-based Extract and Expand Key Derivation Function 799 | def derivation_keys(shared_key): 800 | hkdf = HKDF( 801 | algorithm = hashes.SHA256() , 802 | length = 32 , 803 | salt = shared_key[16:32], 804 | info = shared_key[:16] , 805 | backend = default_backend()) 806 | 807 | keyDerived = hkdf.derive(shared_key[16:]) 808 | return keyDerived 809 | 810 | 811 | # AES Encryption Part 812 | def aes_encryption_func(keyDerived, shared_key, message): 813 | if not type(message) == bytes: 814 | message = message.encode(utf_type) 815 | 816 | if not type(shared_key) == bytes: 817 | shared_key = shared_key.encode(utf_type) 818 | 819 | if not type(keyDerived) == bytes: 820 | keyDerived = keyDerived.encode(utf_type) 821 | 822 | length = 16 - (len(message) % 16) 823 | message += bytes([length]) * length 824 | backend = default_backend() 825 | key = keyDerived 826 | iv = shared_key[:16] 827 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 828 | encryptor = cipher.encryptor() 829 | encrypted = encryptor.update(message) + encryptor.finalize() 830 | 831 | return encrypted 832 | 833 | 834 | # AES Decryption Part 835 | def aes_decryption_func(keyDerived, shared_key, message): 836 | if not type(message) == bytes: 837 | message = message.encode(utf_type) 838 | 839 | if not type(shared_key) == bytes: 840 | shared_key = shared_key.encode(utf_type) 841 | 842 | if not type(keyDerived) == bytes: 843 | keyDerived = keyDerived.encode(utf_type) 844 | 845 | backend = default_backend() 846 | key = keyDerived 847 | iv = shared_key[:16] 848 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 849 | decryptor = cipher.decryptor() 850 | dt = decryptor.update(message) + decryptor.finalize() 851 | decrypted = dt[:-dt[-1]].decode(utf_type) 852 | return decrypted 853 | 854 | 855 | # Controlling prevHash and blockchaindb hash 856 | def check_previous_hash(prevHashs, who): 857 | info('Controlling prevHash and blockchaindb hash!') 858 | global prevhash_curr, phash_curr 859 | 860 | if prevHashs == prevhash_curr: 861 | info('prevHash is verified.') 862 | return True 863 | 864 | elif detect_block(who) == 3: 865 | info('Controlling inside of QueueConf...') 866 | 867 | # Check if the block is in the QueueConf 868 | if get_size_queue(queue_conf) != 0: 869 | 870 | for qs in range(0, get_size_queue(queue_conf)): 871 | tmpY = loading_object(get_from_queue(queue_conf)) 872 | 873 | try: 874 | if prevHashs == tmpY.prevHash: 875 | info('The block is found inside the QueueConf!') 876 | tempF = 1 877 | else: 878 | tempF = 0 879 | 880 | except AttributeError: 881 | tempF = 0 882 | break 883 | 884 | put_queue(queue_temp2, dumping_object(tmpY)) 885 | 886 | # Get back items in temp_hash_q_2ueue to queue_conf 887 | for qItems in range(0, get_size_queue(queue_temp2)): 888 | put_queue(queue_conf, get_from_queue(queue_temp2)) 889 | 890 | # Remove all items from the temp_hash_q_2ueue 891 | for Qitems in range(0, get_size_queue(queue_temp2)): 892 | get_from_queue(queue_temp2) 893 | 894 | if tempF == 1: 895 | return True 896 | 897 | # If the block was added to the blockchain 898 | elif prevHashs == phash_curr: 899 | info('The block was added to the blockchain') 900 | return True 901 | 902 | debug('prevHash is NOT verified!') 903 | return False 904 | 905 | 906 | def add_block_to_chain(Block): 907 | global blockid_curr, prevhash_curr, phash_curr, last_idcurr 908 | Block.blockID = str(int(blockid_curr) + 1) 909 | blockid_curr = int(blockid_curr) + 1 910 | prevhash_curr = Block.hash 911 | phash_curr = Block.prevHash 912 | db.blocks.insert({ 913 | "blockID" : Block.blockID , 914 | "senderID" : Block.senderID , 915 | "receiverID" : Block.receiverID , 916 | "message" : Block.message , 917 | "timestamp" : Block.timestamp , 918 | "hash" : Block.hash , 919 | "prevHash" : Block.prevHash , 920 | "digitalSignature" : Block.digitalSignature, 921 | "verKey" : Block.verKey , 922 | "nonce" : Block.nonce , 923 | "who" : Block.who , 924 | "totalHash" : Block.totalHash 925 | }) 926 | warning('New block added to the blockchain!') 927 | Blockcurr = getlastBlock() 928 | last_idcurr = Blockcurr._id 929 | 930 | 931 | # Compare blockchain hash and received block prevHash 932 | def controlChain(Hash): 933 | try: 934 | for docs in db.blocks.find({'hash': str(Hash)[2:-1]}): 935 | return True 936 | return False 937 | except: 938 | return False 939 | 940 | 941 | # Encoder class for mongodb blocks 942 | class Encoder(JSONEncoder): 943 | def default(self, obj): 944 | if isinstance(obj, ObjectId): 945 | return str(obj) 946 | else: 947 | return obj 948 | 949 | 950 | # Decoder func. for receiving mongodb blocks 951 | def decoder(dct): 952 | for k, v in dct.items(): 953 | if '_id' in dct: 954 | try: 955 | dct['_id'] = ObjectId(dct['_id']) 956 | except: 957 | pass 958 | return dct 959 | 960 | 961 | # Sign the block 962 | def sign_block(Block): 963 | global ecdh_obj 964 | Block.verKey = b64encode(ecdh_obj.messageSign(Block.totalHash)).decode("ISO-8859-1") 965 | 966 | 967 | # Broadcast the block to all chains and miners 968 | def broadcast(Block): 969 | info('Broadcasting to all blockchain servers...') 970 | for hosts in chain_hosts: 971 | while True: 972 | if int(queue_block_who.qsize()) != 0: 973 | Block.who = queue_block_who.get() 974 | break 975 | sleep(0.05) 976 | fakeID_1 = randint(0, 999999999999999999999999) 977 | fakeID_2 = randint(0, 999999999999999999999999) 978 | Block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 979 | sign_block(Block) 980 | connect(hosts, Block) 981 | 982 | 983 | # User Operations... 984 | def user_operations(): 985 | while True: 986 | 987 | while True: 988 | if int(queue_user.qsize()) != 0: 989 | infos = get_from_queue(queue_user) 990 | block = infos[0] 991 | IP_Add = infos[1] 992 | break 993 | 994 | lock_user.acquire() 995 | while True: 996 | # Block has something: 997 | if block != "": 998 | hashFlag = 0 999 | try: 1000 | if controlling_hash(block, 1): 1001 | 1002 | if block.prevHash[0:7] == "b'00000": 1003 | hashFlag = 1 1004 | 1005 | else: 1006 | info('Controlling hash is FALSE! 2') 1007 | hashFlag = 0 1008 | break 1009 | 1010 | else: 1011 | info('Controlling hash is FALSE! 1') 1012 | hashFlag = 0 1013 | break 1014 | 1015 | except: 1016 | info('Controlling hash has an ERROR..!') 1017 | hashFlag = 0 1018 | break 1019 | 1020 | if hashFlag == 1: 1021 | 1022 | # If the block comes from the user to confirm.. 1023 | if block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1024 | str(code_block_10).encode(utf_type)).hexdigest(): 1025 | 1026 | try: 1027 | if controlChain(block.prevHash): 1028 | chainF = 1 1029 | info('Chain control result is TRUE.') 1030 | 1031 | else: 1032 | info('Chain control result is FALSE!') 1033 | # Re-Send the block with code-8 1034 | chainF = 0 1035 | 1036 | except: 1037 | debug('Chain controlling ERROR..!') 1038 | chainF = 0 1039 | 1040 | if chainF == 0: 1041 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1042 | str(code_block_08).encode(utf_type)).hexdigest() 1043 | 1044 | while True: 1045 | if int(queue_block_who.qsize()) != 0: 1046 | block.who = queue_block_who.get() 1047 | break 1048 | sleep(0.05) 1049 | 1050 | # Change blockID value for attacks 1051 | fakeID_1 = randint(0, 999999999999999999999999) 1052 | fakeID_2 = randint(0, 999999999999999999999999) 1053 | block.blockID = SHA512.new(str(fakeID_1 + 1054 | fakeID_2).encode(utf_type)).hexdigest() 1055 | sign_block(block) 1056 | connect(IP_Add, block) 1057 | 1058 | # Chain control result is TRUE 1059 | elif chainF == 1: 1060 | info('The block is already in the blockchain.') 1061 | 1062 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1063 | str(code_block_09).encode(utf_type)).hexdigest() 1064 | 1065 | # Send it with Block.hash is NoK 1066 | while True: 1067 | if int(queue_block_who.qsize()) != 0: 1068 | block.who = queue_block_who.get() 1069 | break 1070 | sleep(0.05) 1071 | 1072 | # Change blockID value for attacks 1073 | fakeID_1 = randint(0, 999999999999999999999999) 1074 | fakeID_2 = randint(0, 999999999999999999999999) 1075 | block.blockID = SHA512.new(str(fakeID_1 + 1076 | fakeID_2).encode(utf_type)).hexdigest() 1077 | sign_block(block) 1078 | connect(IP_Add, block) 1079 | 1080 | break 1081 | 1082 | break 1083 | 1084 | break 1085 | 1086 | break 1087 | 1088 | lock_user.release() 1089 | 1090 | 1091 | # Blockchain Operations... 1092 | def chain_operations(): 1093 | while True: 1094 | 1095 | while True: 1096 | if int(queue_chain.qsize()) != 0: 1097 | infos = get_from_queue(queue_chain) 1098 | block = infos[0] 1099 | IP_Add = infos[1] 1100 | break 1101 | 1102 | lock_chain.acquire() 1103 | while True: 1104 | # Block has something: 1105 | if block != "": 1106 | 1107 | # If block came.. 1108 | try: 1109 | if controlling_hash(block, 3): 1110 | hashFlag = 1 1111 | 1112 | else: 1113 | info('Controlling hash is FALSE! 3') 1114 | hashFlag = 0 1115 | break 1116 | 1117 | except: 1118 | info('Controlling hash has an ERROR..!') 1119 | hashFlag = 0 1120 | break 1121 | 1122 | try: 1123 | if checking_block_id(block): 1124 | blockIDF = 1 1125 | info('ID of the block control result is TRUE. [2]') 1126 | 1127 | else: 1128 | blockIDF = 0 1129 | info('ID of the block control result is FALSE! [2]') 1130 | 1131 | except: 1132 | blockIDF = 0 1133 | debug('ID of the block control ERROR..! [2]') 1134 | break 1135 | 1136 | if hashFlag == 1 and blockIDF == 1: 1137 | 1138 | debug('The block is coming from the blockchain(s) server!') 1139 | global blockid_curr, prevhash_curr, last_idcurr 1140 | 1141 | # If it is request block 1142 | if block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1143 | str(code_block_06).encode(utf_type)).hexdigest(): 1144 | info('It is a request block..') 1145 | 1146 | try: 1147 | if check_previous_hash(block.prevHash, block.who): 1148 | info('Checking previous hash is TRUE.[1]') 1149 | prevFlag = 1 1150 | 1151 | else: 1152 | prevFlag = 0 1153 | info('Checking previous hash is FALSE!') 1154 | 1155 | except: 1156 | prevFlag = 0 1157 | debug('Checking previous hash has something wrong!') 1158 | break 1159 | 1160 | # Controlling prevHash.. 1161 | if prevFlag == 1: 1162 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1163 | str(code_block_05).encode(utf_type)).hexdigest() 1164 | 1165 | # Send it with OK 1166 | while True: 1167 | if int(queue_block_who.qsize()) != 0: 1168 | block.who = queue_block_who.get() 1169 | break 1170 | sleep(0.05) 1171 | 1172 | # Change blockID value for attacks 1173 | fakeID_1 = randint(0, 999999999999999999999999) 1174 | fakeID_2 = randint(0, 999999999999999999999999) 1175 | block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 1176 | 1177 | # False prevHash, so send it with NoK 1178 | else: 1179 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1180 | str(code_block_04).encode(utf_type)).hexdigest() 1181 | # Send it with NoK 1182 | while True: 1183 | if int(queue_block_who.qsize()) != 0: 1184 | block.who = queue_block_who.get() 1185 | break 1186 | sleep(0.05) 1187 | 1188 | # Change blockID value for attacks 1189 | fakeID_1 = randint(0, 999999999999999999999999) 1190 | fakeID_2 = randint(0, 999999999999999999999999) 1191 | block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 1192 | 1193 | sign_block(block) 1194 | connect(IP_Add, block) 1195 | 1196 | # If it is OK Block 1197 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1198 | str(code_block_05).encode(utf_type)).hexdigest(): 1199 | info('It is OK Block') 1200 | # Get object and flag values if exists 1201 | calcObj, createF = find_obj(block.hash, IP_Add) 1202 | 1203 | # Already created, check IP 1204 | if createF == 1: 1205 | for IPs in calcObj.IP: 1206 | if IPs == IP_Add: 1207 | dupF = 0 1208 | debug('Duplicated block has come!') 1209 | break 1210 | else: 1211 | dupF = 1 1212 | 1213 | elif createF == 0: 1214 | dupF = 1 1215 | 1216 | # If answer is NOT duplicated one. 1217 | if dupF == 1: 1218 | info('OK is increased by 1.') 1219 | calcObj.ok += 1 1220 | # Empty Queue 1221 | if get_size_queue(queue_temp1) != 0: 1222 | for qs in range(0, get_size_queue(queue_temp1)): 1223 | get_from_queue(queue_temp1) 1224 | 1225 | for qs in range(0, get_size_queue(queue_conf)): 1226 | tempBlock = loading_object(get_from_queue(queue_conf)) 1227 | 1228 | if tempBlock.hash == block.hash: 1229 | info('queue_conf.hash and block.hash are same!') 1230 | 1231 | if len(chain_hosts) / 2 < int(calcObj.ok): 1232 | info('Hosts OK & NoK are verified!') 1233 | remove_obj(block.hash) 1234 | 1235 | if int(calcObj.ok) > int(calcObj.NoK): 1236 | calcHash = main_block(block, 2) 1237 | 1238 | if str(calcHash) == str(block.hash): 1239 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1240 | str(code_block_07).encode(utf_type)).hexdigest() 1241 | block.who = 1 1242 | add_block_to_chain(block) 1243 | 1244 | if int(queue_conf.qsize()) != 0: 1245 | get_from_queue(queue_conf) 1246 | 1247 | if int(queue_conftimer.qsize()) != 0: 1248 | get_from_queue(queue_conftimer) 1249 | 1250 | if int(queue_verify.qsize()) != 0: 1251 | get_from_queue(queue_verify) 1252 | 1253 | if int(queue_verifytimer.qsize()) != 0: 1254 | get_from_queue(queue_verifytimer) 1255 | 1256 | broadcast(block) 1257 | 1258 | break 1259 | else: 1260 | debug('queue_conf.hash and block.hash are NOT same!') 1261 | put_queue(queue_conf, dumping_object(block)) 1262 | 1263 | # If it is NoK Block 1264 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1265 | str(code_block_04).encode(utf_type)).hexdigest(): 1266 | info('It is NoK Block') 1267 | calcObj, createF = find_obj(block.hash, IP_Add) 1268 | if createF == 1: 1269 | 1270 | for IPs in calcObj.IP: 1271 | if IPs == IP_Add: 1272 | dupF = 0 1273 | debug('Duplicated block has come!') 1274 | break 1275 | 1276 | else: 1277 | dupF = 1 1278 | 1279 | elif createF == 0: 1280 | dupF = 1 1281 | 1282 | if dupF == 1: 1283 | calcObj.NoK += 1 1284 | 1285 | # If lastBlock check request 1286 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1287 | str(code_block_06).encode(utf_type) + 1288 | str(code_block_11).encode(utf_type)).hexdigest(): 1289 | 1290 | info('It is a lastBlock control request!') 1291 | 1292 | if block.hash == prevhash_curr: 1293 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1294 | str(code_block_01).encode(utf_type) + 1295 | str(code_block_03).encode(utf_type)).hexdigest() 1296 | while True: 1297 | if int(queue_block_who.qsize()) != 0: 1298 | block.who = queue_block_who.get() 1299 | break 1300 | sleep(0.05) 1301 | 1302 | fakeID_1 = randint(0, 999999999999999999999999) 1303 | fakeID_2 = randint(0, 999999999999999999999999) 1304 | block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 1305 | 1306 | sign_block(block) 1307 | connect(IP_Add, block) 1308 | 1309 | elif block.prevHash == prevhash_curr: 1310 | calcHash = main_block(block, 2) 1311 | 1312 | if str(calcHash) == str(block.hash): 1313 | 1314 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1315 | str(code_block_07).encode(utf_type)).hexdigest() 1316 | block.who = 1 1317 | add_block_to_chain(block) 1318 | 1319 | if int(queue_conf.qsize()) != 0: 1320 | get_from_queue(queue_conf) 1321 | 1322 | if int(queue_conftimer.qsize()) != 0: 1323 | get_from_queue(queue_conftimer) 1324 | 1325 | if int(queue_verify.qsize()) != 0: 1326 | get_from_queue(queue_verify) 1327 | 1328 | if int(queue_verifytimer.qsize()) != 0: 1329 | get_from_queue(queue_verifytimer) 1330 | 1331 | broadcast(block) 1332 | 1333 | # If lastBlock is NoK 1334 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1335 | str(code_block_04).encode(utf_type) + 1336 | str(code_block_00).encode(utf_type)).hexdigest(): 1337 | info('lastBlock is NoK') 1338 | 1339 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1340 | str(code_block_12).encode(utf_type)).hexdigest() 1341 | while True: 1342 | if int(queue_block_who.qsize()) != 0: 1343 | block.who = queue_block_who.get() 1344 | break 1345 | sleep(0.05) 1346 | 1347 | fakeID_1 = randint(0, 999999999999999999999999) 1348 | fakeID_2 = randint(0, 999999999999999999999999) 1349 | block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 1350 | 1351 | sign_block(block) 1352 | connect(IP_Add, block) 1353 | 1354 | # If lastBlock is OK 1355 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1356 | str(code_block_01).encode(utf_type) + 1357 | str(code_block_03).encode(utf_type)).hexdigest(): 1358 | info('lastBlock is OK..') 1359 | 1360 | # Send your blocks request 1361 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1362 | str(code_block_12).encode(utf_type)).hexdigest(): 1363 | info('Send your blocks request...') 1364 | 1365 | while True: 1366 | for docs in db.blocks.find(): 1367 | if str(last_idcurr) == str(obj(docs)._id): 1368 | checkF = 1 1369 | lastblockID = str(obj(docs).blockID) 1370 | break 1371 | else: 1372 | checkF = 0 1373 | lastblockID = 0 1374 | 1375 | if checkF == 1 and lastblockID != 0: 1376 | nowblockID = blockid_curr 1377 | for IDs in range(int(lastblockID), int(nowblockID)): 1378 | for docs in db.blocks.find({'blockID': str(IDs)}): 1379 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1380 | str(code_block_10).encode(utf_type) + 1381 | str(code_block_11).encode(utf_type) + 1382 | str(code_block_12).encode(utf_type)).hexdigest() 1383 | while True: 1384 | if int(queue_block_who.qsize()) != 0: 1385 | block.who = queue_block_who.get() 1386 | break 1387 | sleep(0.05) 1388 | 1389 | fakeID_1 = randint(0, 999999999999999999999999) 1390 | fakeID_2 = randint(0, 999999999999999999999999) 1391 | block.blockID = SHA512.new( 1392 | str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 1393 | 1394 | sign_block(block) 1395 | connect(IP_Add, block) 1396 | break 1397 | 1398 | # Add the new block (reply) 1399 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1400 | str(code_block_10).encode(utf_type) + 1401 | str(code_block_11).encode(utf_type) + 1402 | str(code_block_12).encode(utf_type)).hexdigest(): 1403 | info('Add the new block reply..!') 1404 | calcHash = main_block(block, 2) 1405 | if str(calcHash) == str(block.hash): 1406 | if block.prevHash == str(prevhash_curr): 1407 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1408 | str(code_block_07).encode(utf_type)).hexdigest() 1409 | block.who = 1 1410 | add_block_to_chain(block) 1411 | 1412 | if int(queue_conf.qsize()) != 0: 1413 | get_from_queue(queue_conf) 1414 | 1415 | if int(queue_conftimer.qsize()) != 0: 1416 | get_from_queue(queue_conftimer) 1417 | 1418 | if int(queue_verify.qsize()) != 0: 1419 | get_from_queue(queue_verify) 1420 | 1421 | if int(queue_verifytimer.qsize()) != 0: 1422 | get_from_queue(queue_verifytimer) 1423 | 1424 | broadcast(block) 1425 | 1426 | # Means other chain server added the block 1427 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1428 | str(code_block_07).encode(utf_type)).hexdigest(): 1429 | info('Other blockchain server added the block.') 1430 | 1431 | calcHash = main_block(block, 2) 1432 | if str(calcHash) == str(block.hash): 1433 | if block.prevHash == prevhash_curr: 1434 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1435 | str(code_block_07).encode(utf_type)).hexdigest() 1436 | block.who = 1 1437 | add_block_to_chain(block) 1438 | 1439 | if int(queue_conf.qsize()) != 0: 1440 | get_from_queue(queue_conf) 1441 | 1442 | if int(queue_conftimer.qsize()) != 0: 1443 | get_from_queue(queue_conftimer) 1444 | 1445 | if int(queue_verify.qsize()) != 0: 1446 | get_from_queue(queue_verify) 1447 | 1448 | if int(queue_verifytimer.qsize()) != 0: 1449 | get_from_queue(queue_verifytimer) 1450 | 1451 | broadcast(block) 1452 | 1453 | else: 1454 | info('It is NULL..') 1455 | 1456 | break 1457 | 1458 | lock_chain.release() 1459 | 1460 | 1461 | # Block operations 1462 | def miner_operations(): 1463 | while True: 1464 | while True: 1465 | if int(queue_miner.qsize()) != 0: 1466 | infos = get_from_queue(queue_miner) 1467 | block = infos[0] 1468 | IP_Add = infos[1] 1469 | break 1470 | 1471 | lock_miner.acquire() 1472 | while True: 1473 | # Block has something: 1474 | if block != "": 1475 | 1476 | try: 1477 | if controlling_hash(block, 2): 1478 | hashFlag = 1 1479 | 1480 | else: 1481 | info('Controlling hash is FALSE 5') 1482 | hashFlag = 0 1483 | break 1484 | 1485 | except: 1486 | info('Controlling hash has an ERROR.! 6') 1487 | hashFlag = 0 1488 | break 1489 | 1490 | try: 1491 | if checking_block_id(block): 1492 | blockIDF = 1 1493 | info('ID of the block control result is TRUE. [3]') 1494 | 1495 | else: 1496 | blockIDF = 0 1497 | info('ID of the block control result is FALSE! [3]') 1498 | 1499 | except: 1500 | blockIDF = 0 1501 | debug('ID of the block control ERROR! [3]') 1502 | break 1503 | 1504 | if hashFlag == 1 and blockIDF == 1: 1505 | # Block comes from the miner servers 1506 | debug('The block is coming from the miner(s) side!') 1507 | 1508 | try: 1509 | if check_previous_hash(block.prevHash, block.who): 1510 | info('Checking previous hash is TRUE.[2]') 1511 | prevFlag = 1 1512 | else: 1513 | prevFlag = 0 1514 | info('Checking previous hash is FALSE!') 1515 | 1516 | except: 1517 | prevFlag = 0 1518 | debug('Checking previous hash has something WRONG!') 1519 | break 1520 | 1521 | if prevFlag == 1: 1522 | 1523 | try: 1524 | # Check digital signature in the block 1525 | verifyFlag = 0 1526 | 1527 | global ecdh_obj 1528 | for publics in storage_pub: 1529 | if str(IP_Add) == str(publics[1]): 1530 | if ecdh_obj.verifyMSG(public_key = publics[0] , 1531 | message = block.totalHash, 1532 | sign = block.verKey): 1533 | info('Message verifying result is TRUE.') 1534 | verifyFlag = 1 1535 | break 1536 | 1537 | except: 1538 | info('Message verifying result has an ERROR!') 1539 | verifyFlag = 0 1540 | break 1541 | 1542 | # Message verified.. 1543 | if verifyFlag == 1: 1544 | 1545 | countQverify = get_size_queue(queue_verify) 1546 | # Check block for verify queue.. 1547 | for qs in range(0, get_size_queue(queue_verify)): 1548 | tmpBlock = loading_object(get_from_queue(queue_verify)) 1549 | tmpT = get_from_queue(queue_verifytimer) 1550 | 1551 | # Check received block already exists! 1552 | if block.hash == tmpBlock.hash: 1553 | info('Block already exists in the Queue..!') 1554 | # Send the block to the miner with code-3 OK 1555 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1556 | str(code_block_03).encode(utf_type)).hexdigest() 1557 | 1558 | while True: 1559 | if int(queue_block_who.qsize()) != 0: 1560 | block.who = queue_block_who.get() 1561 | break 1562 | sleep(0.05) 1563 | 1564 | # Change blockID value for attacks 1565 | fakeID_1 = randint(0, 999999999999999999999999) 1566 | fakeID_2 = randint(0, 999999999999999999999999) 1567 | block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 1568 | 1569 | # IP address validation for miner_hosts 1570 | sign_block(block) 1571 | connect(IP_Add, block) 1572 | 1573 | # Calculate hash with requestCode-6 1574 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1575 | str(code_block_06).encode(utf_type)).hexdigest() 1576 | 1577 | # Change blockID value for attacks 1578 | fakeID_1 = randint(0, 999999999999999999999999) 1579 | fakeID_2 = randint(0, 999999999999999999999999) 1580 | block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 1581 | 1582 | # Add the block to the queue 1583 | put_queue(queue_conf, dumping_object(block)) 1584 | put_queue(queue_conftimer, 5) 1585 | 1586 | # Broadcast the block to all chain servers 1587 | for hosts in chain_hosts: 1588 | while True: 1589 | if int(queue_block_who.qsize()) != 0: 1590 | block.who = queue_block_who.get() 1591 | break 1592 | sleep(0.05) 1593 | 1594 | sign_block(block) 1595 | connect(hosts, block) 1596 | 1597 | break 1598 | 1599 | put_queue(queue_verify, dumping_object(tmpBlock)) 1600 | put_queue(queue_verifytimer, tmpT) 1601 | 1602 | # If the QVerify size decreases by 1 1603 | if countQverify == get_size_queue(queue_verify) + 1: 1604 | pass 1605 | 1606 | # If no blocks are in the QVerify 1607 | else: 1608 | info('The block is NOT in the QVerify.') 1609 | 1610 | put_queue(queue_verify, dumping_object(block)) 1611 | put_queue(queue_verifytimer, 5) 1612 | 1613 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1614 | str(code_block_03).encode(utf_type)).hexdigest() 1615 | 1616 | # Change blockID value for attacks 1617 | fakeID_1 = randint(0, 999999999999999999999999) 1618 | fakeID_2 = randint(0, 999999999999999999999999) 1619 | block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 1620 | 1621 | # Send it with Block is OK 1622 | while True: 1623 | if int(queue_block_who.qsize()) != 0: 1624 | block.who = queue_block_who.get() 1625 | break 1626 | sleep(0.05) 1627 | 1628 | sign_block(block) 1629 | connect(IP_Add, block) 1630 | 1631 | break 1632 | 1633 | # Get values from the last block 1634 | if get_size_queue(queue_conf) != 0 or get_size_queue(queue_verify) != 0: 1635 | block_id_rndm = '0' 1636 | fakeHash_1 = randint(0, 999999999999999999999999) 1637 | fakeHash_2 = randint(0, 999999999999999999999999) 1638 | prev_hash_rndm = SHA512.new(str(fakeHash_1 + fakeHash_2).encode(utf_type)).hexdigest() 1639 | 1640 | else: 1641 | global blockid_curr, prevhash_curr 1642 | block_id_rndm = int(blockid_curr) + 1 1643 | prev_hash_rndm = prevhash_curr 1644 | 1645 | # Add whois information 1646 | info('ID and prevHash values are getting, added to the block.') 1647 | 1648 | # Calculate hash of blockID 1649 | hash_block_id = SHA512.new(str(block_id_rndm).encode(utf_type)).hexdigest() 1650 | block.blockID = hash_block_id 1651 | block.prevHash = prev_hash_rndm 1652 | 1653 | # Re-calculation of block totalHash value 1654 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1655 | str(code_block_11).encode(utf_type)).hexdigest() 1656 | 1657 | while True: 1658 | if int(queue_block_who.qsize()) != 0: 1659 | block.who = queue_block_who.get() 1660 | break 1661 | sleep(0.05) 1662 | 1663 | sign_block(block) 1664 | connect(IP_Add, block) 1665 | 1666 | break 1667 | 1668 | lock_miner.release() 1669 | 1670 | 1671 | # SERVER SIDE 1672 | # Receive data from the socket 1673 | class ClientThread(Thread): 1674 | def __init__(self, conn, ip_address): 1675 | Thread.__init__(self) 1676 | self.ip_address = ip_address 1677 | self.conn = conn 1678 | 1679 | def run(self): 1680 | while True: 1681 | # Receive bytes 1682 | connFlag = 1 1683 | conFlag = 1 1684 | 1685 | try: 1686 | tempBytes = self.conn.recv(4096) 1687 | 1688 | #except: 1689 | # break 1690 | 1691 | global shared_pairs 1692 | global tempBlock 1693 | global ecdh_obj 1694 | global certificate 1695 | if str(shared_pairs) == '0' and len(codes_of_block) == 0: 1696 | 1697 | # If the public key received 1698 | try: 1699 | 1700 | if len(codes_of_block) == 0: 1701 | 1702 | if str(tempBytes.decode(utf_type)).startswith("-----BEGIN PUBLIC KEY-----") and\ 1703 | "-----END PUBLIC KEY-----" in str(tempBytes.decode(utf_type)): 1704 | shared_pairs = ecdh_obj.found_shared_secret(deserialize_pubkey(tempBytes)) 1705 | certificate = tempBytes 1706 | tempBlock = [] 1707 | break 1708 | 1709 | else: 1710 | break 1711 | 1712 | break 1713 | 1714 | except: 1715 | pass 1716 | 1717 | elif str(shared_pairs) != '0' and len(codes_of_block) == 0: 1718 | 1719 | try: 1720 | tempBlock.append(tempBytes) 1721 | 1722 | if len(tempBlock) == 13: 1723 | 1724 | for blockcodes in tempBlock: 1725 | codes_of_block.append(aes_decryption_func(derivation_keys(shared_pairs), shared_pairs, blockcodes)) 1726 | 1727 | global code_block_00, code_block_01, code_block_02, code_block_03 1728 | global code_block_04, code_block_05, code_block_06, code_block_07 1729 | global code_block_08, code_block_09, code_block_10, code_block_11 1730 | global code_block_11, code_block_12 1731 | 1732 | code_block_12 = SHA512.new(str(codes_of_block[12]).encode(utf_type)).hexdigest() 1733 | code_block_11 = SHA512.new(str(codes_of_block[11]).encode(utf_type)).hexdigest() 1734 | code_block_10 = SHA512.new(str(codes_of_block[10]).encode(utf_type)).hexdigest() 1735 | code_block_09 = SHA512.new(str(codes_of_block[9]) .encode(utf_type)).hexdigest() 1736 | code_block_08 = SHA512.new(str(codes_of_block[8]) .encode(utf_type)).hexdigest() 1737 | code_block_07 = SHA512.new(str(codes_of_block[7]) .encode(utf_type)).hexdigest() 1738 | code_block_06 = SHA512.new(str(codes_of_block[6]) .encode(utf_type)).hexdigest() 1739 | code_block_05 = SHA512.new(str(codes_of_block[5]) .encode(utf_type)).hexdigest() 1740 | code_block_04 = SHA512.new(str(codes_of_block[4]) .encode(utf_type)).hexdigest() 1741 | code_block_03 = SHA512.new(str(codes_of_block[3]) .encode(utf_type)).hexdigest() 1742 | code_block_02 = SHA512.new(str(codes_of_block[2]) .encode(utf_type)).hexdigest() 1743 | code_block_01 = SHA512.new(str(codes_of_block[1]) .encode(utf_type)).hexdigest() 1744 | code_block_00 = SHA512.new(str(codes_of_block[0]) .encode(utf_type)).hexdigest() 1745 | 1746 | for blocks in tempBlock: 1747 | tempBlock.remove(blocks) 1748 | del blocks 1749 | 1750 | break 1751 | 1752 | except: 1753 | pass 1754 | 1755 | else: 1756 | # If others public came.. 1757 | try: 1758 | changed = 0 1759 | public = aes_decryption_func(derivation_keys(shared_pairs), shared_pairs, tempBytes).encode(utf_type) 1760 | IP = public.decode('utf-8').split('\n')[-1] 1761 | 1762 | for publics in storage_pub: 1763 | if publics[1] == IP: 1764 | publics = ((deserialize_pubkey(public), IP)) 1765 | changed = 1 1766 | 1767 | if changed == 0: 1768 | storage_pub.append((deserialize_pubkey(public), IP)) 1769 | 1770 | except: 1771 | pass 1772 | 1773 | # Block Reloading.. 1774 | try: 1775 | block = loadRecv(l0(tempBytes).decode("ISO-8859-1")) 1776 | block = obj(block) 1777 | 1778 | except: 1779 | 1780 | try: 1781 | block = loads(l0(tempBytes).decode("ISO-8859-1"), object_hook=decoder) 1782 | block = obj(block) 1783 | 1784 | except: 1785 | 1786 | try: 1787 | block = l0(tempBytes) 1788 | 1789 | except: 1790 | break 1791 | 1792 | # IP address validation for chain_hosts 1793 | for hosts in chain_hosts: 1794 | if hosts == self.ip_address: 1795 | info('IP [' + str(self.ip_address) + '] is in the chain list.') 1796 | connFlag = 1 1797 | conFlag = 0 1798 | break 1799 | 1800 | else: 1801 | connFlag = 0 1802 | conFlag = 0 1803 | 1804 | # If the chain list does NOT contains IP address 1805 | if connFlag == 0: 1806 | # IP address validation for miner_hosts 1807 | for hosts in miner_hosts: 1808 | if hosts == self.ip_address: 1809 | info('IP [' + str(self.ip_address) + '] is in the miner list.') 1810 | conFlag = 1 1811 | break 1812 | 1813 | else: 1814 | conFlag = 0 1815 | 1816 | # The data is coming from the UNKNOWN sender 1817 | if conFlag == 0 and connFlag == 0: 1818 | if self.ip_address != auth_host: 1819 | debug('UNKNOWN Sender !!!') 1820 | break 1821 | else: 1822 | info('IP [' + str(self.ip_address) + '] is authentication list.') 1823 | 1824 | # If Data does NOT LOAD! 1825 | except ConnectionResetError: 1826 | debug('Connection Reset by [' + self.ip_address + ']') 1827 | break 1828 | 1829 | except AttributeError: 1830 | debug('Data is broken !') 1831 | break 1832 | 1833 | except: 1834 | warning('Connection ERROR !') 1835 | break 1836 | 1837 | info('[' + self.ip_address + '] is connected.') 1838 | 1839 | try: 1840 | blockWho = detect_block(block.who) 1841 | 1842 | except AttributeError: 1843 | pass 1844 | 1845 | except UnboundLocalError: 1846 | pass 1847 | 1848 | except: 1849 | debug('flag_who control result has something wrong!') 1850 | break 1851 | 1852 | try: 1853 | # If the user sends the block 1854 | if blockWho == 1: 1855 | info('The user sends the block!') 1856 | put_queue(queue_user, (block, self.ip_address)) 1857 | 1858 | # If the mining part sends the block 1859 | elif blockWho == 2: 1860 | info('The miner sends the block!') 1861 | put_queue(queue_miner, (block, self.ip_address)) 1862 | 1863 | # If the blockchain part sends the block 1864 | elif blockWho == 3: 1865 | info('The blockchain sends the block!') 1866 | put_queue(queue_chain, (block, self.ip_address)) 1867 | 1868 | else: 1869 | debug('Someone sends the block!') 1870 | 1871 | except: 1872 | pass 1873 | 1874 | break 1875 | 1876 | 1877 | 1878 | # Listen all connections 1879 | def Conn(): 1880 | info('Server is preparing..') 1881 | tcpServer = socket(AF_INET, SOCK_STREAM) 1882 | tcpServer.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 1883 | 1884 | tcpServer.bind((binding_address, port_number)) 1885 | tcpServer.listen(200) 1886 | 1887 | context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH) 1888 | context.load_cert_chain('selfsigned.cert', 'selfsigned.key') 1889 | context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 1890 | context.set_ciphers('EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH') 1891 | 1892 | threads = [] 1893 | info('Server side is ready to listen.') 1894 | 1895 | while True: 1896 | 1897 | try: 1898 | (conn, (ip_address, port_number_ADD)) = tcpServer.accept() 1899 | info('[' + str(ip_address) + ']:[' + str(port_number_ADD) + '] is connecting...') 1900 | conn = context.wrap_socket(conn, server_side=True) 1901 | newthread = ClientThread(conn, ip_address) 1902 | newthread.start() 1903 | threads.append(newthread) 1904 | 1905 | except ssl.SSLError: 1906 | debug('Sender does NOT use SSL..!') 1907 | 1908 | except: 1909 | pass 1910 | 1911 | try: 1912 | if not threads[0].is_alive(): 1913 | del threads[0] 1914 | except: 1915 | pass 1916 | 1917 | for t in threads: 1918 | t.join() 1919 | 1920 | 1921 | def quitLog(): 1922 | warning('----------------------------------------') 1923 | warning('--- Blockchain Server is stopping... ---') 1924 | warning('----------------------------------------') 1925 | 1926 | 1927 | def startLog(): 1928 | warning('++++++++++++++++++++++++++++++++++++++++') 1929 | warning('+++ Blockchain Server is starting... +++') 1930 | warning('++++++++++++++++++++++++++++++++++++++++') 1931 | 1932 | 1933 | # CLIENT SIDE 1934 | # Send any block to others 1935 | def connect(HOST, message): 1936 | info('Message is sending to [' + str(HOST) + ']') 1937 | 1938 | # Socket informations 1939 | try: 1940 | mySocket = socket(AF_INET, SOCK_STREAM) 1941 | mySocket.settimeout(2) 1942 | context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH) 1943 | context.check_hostname = False 1944 | context.load_cert_chain('selfsigned.cert', 'selfsigned.key') 1945 | context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 1946 | conn = context.wrap_socket(mySocket) 1947 | conn.connect((HOST, port_number)) 1948 | 1949 | # Sending bytes data.. 1950 | if 'bytes' in str(type(message)): 1951 | info('Sending bytes format..') 1952 | conn.send(message) 1953 | 1954 | # '.obj' in str(type(message)) 1955 | else: 1956 | 1957 | info('Sending obj or string format..') 1958 | 1959 | try: 1960 | msg = dumps(message.__dict__) 1961 | except: 1962 | 1963 | try: 1964 | msg = dumps(message.__dict__, cls=Encoder) 1965 | except: 1966 | 1967 | try: 1968 | msg = d0(message) 1969 | except: 1970 | conn.close() 1971 | return False 1972 | 1973 | try: 1974 | conn.send(d0(msg.encode("ISO-8859-1"))) 1975 | except: 1976 | try: 1977 | conn.send(msg) 1978 | except: 1979 | return False 1980 | 1981 | info('Message is sent to [' + str(HOST) + ']') 1982 | conn.close() 1983 | return True 1984 | 1985 | except ConnectionRefusedError: 1986 | debug('Receiver [' + str(HOST) + '] is OFFLINE!') 1987 | return False 1988 | 1989 | except ConnectionResetError: 1990 | debug('Receiver [' + str(HOST) + '] does NOT use SSL!') 1991 | return False 1992 | 1993 | except: 1994 | debug('Receiver [' + str(HOST) + '] seems like OFFLINE!') 1995 | return False 1996 | 1997 | 1998 | # Check if MongoDB is running or not 1999 | def mongo_service(): 2000 | mongo_Proc = Popen(['ps -A | grep mongod'], stdout=PIPE, shell=True) 2001 | (out, err) = mongo_Proc.communicate() 2002 | info('MongoDB process checking..') 2003 | 2004 | if out.decode() == "": 2005 | # If MongoDB service is NOT running 2006 | debug("MongoDB process is NOT running!") 2007 | quitLog() 2008 | sleep(0.5) 2009 | system("pkill -9 python") 2010 | exit() 2011 | 2012 | else: 2013 | info("MongoDB process is running..") 2014 | # If MongoDB service is running 2015 | databaseExists() 2016 | 2017 | 2018 | # Convert MongoDB dict to object 2019 | class obj(object): 2020 | def __init__(self, d): 2021 | 2022 | for a, b in d.items(): 2023 | 2024 | if isinstance(b, (list, tuple)): 2025 | setattr(self, a, [obj(x) if isinstance(x, dict) else x for x in b]) 2026 | 2027 | else: 2028 | setattr(self, a, obj(b) if isinstance(b, dict) else b) 2029 | 2030 | 2031 | # Get last block in MongoDB 2032 | def getlastBlock(): 2033 | lastBlock = db.blocks.find().sort([('_id', -1)]).limit(1) 2034 | info('Lastblock is getting..') 2035 | return obj(lastBlock[0]) 2036 | 2037 | 2038 | def dumpRecv(object): 2039 | return dumps(object) 2040 | 2041 | 2042 | def loadRecv(object): 2043 | return loads(object) 2044 | 2045 | 2046 | # Dump object before sending 2047 | def dumping_object(object): 2048 | info('The object is dumping..') 2049 | return d0(object) 2050 | 2051 | 2052 | # Load received object 2053 | def loading_object(object): 2054 | info('The object is loading..') 2055 | return l0(object) 2056 | 2057 | 2058 | def databaseExists(): 2059 | dbnames = client.database_names() 2060 | 2061 | # Check databasename if exists 2062 | if mongodbName in dbnames: 2063 | info('Database name found.') 2064 | collection = db.blocks 2065 | cursor = collection.find() 2066 | genZero = SHA512.new(str(0).encode(utf_type)).hexdigest() 2067 | genMSG = SHA512.new(str("It's the genesis block.").encode(utf_type)).hexdigest() 2068 | genHash = genesisHash() 2069 | 2070 | try: 2071 | genesisBlock = obj(cursor[0]) 2072 | 2073 | # Check genesis block 2074 | if genesisBlock.blockID == 0 and \ 2075 | genesisBlock.senderID == genZero and \ 2076 | genesisBlock.hash == genHash and \ 2077 | genesisBlock.message == genMSG and \ 2078 | genesisBlock.prevHash == genZero and \ 2079 | genesisBlock.timestamp == genZero and \ 2080 | genesisBlock.receiverID == genZero and \ 2081 | genesisBlock.digitalSignature == genZero and \ 2082 | genesisBlock.verKey == genZero and \ 2083 | genesisBlock.nonce == genZero and \ 2084 | genesisBlock.who == 1 and \ 2085 | genesisBlock.totalHash == genZero: 2086 | 2087 | info('Genesis is verified.') 2088 | 2089 | except IndexError: 2090 | debug('Genesis block does NOT found in the blockchain.') 2091 | 2092 | # Create a genesis block 2093 | genesis_creation() 2094 | 2095 | lastBlock = getlastBlock() 2096 | 2097 | # If chain has many blocks 2098 | if lastBlock.hash != genHash: 2099 | info('Blockchain has more blocks.') 2100 | 2101 | # Send and verify last block is correct 2102 | for hosts in chain_hosts: 2103 | 2104 | lastBlock.totalHash = SHA512.new(str(lastBlock.hash).encode(utf_type) + 2105 | str(code_block_06).encode(utf_type) + 2106 | str(code_block_11).encode(utf_type)).hexdigest() 2107 | 2108 | # Change blockID value for attacks 2109 | fakeID_1 = randint(0, 999999999999999999999999) 2110 | fakeID_2 = randint(0, 999999999999999999999999) 2111 | lastBlock.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 2112 | 2113 | while True: 2114 | if int(queue_block_who.qsize()) != 0: 2115 | lastBlock.who = queue_block_who.get() 2116 | break 2117 | sleep(0.05) 2118 | 2119 | sign_block(lastBlock) 2120 | connResult = connect(hosts, lastBlock) 2121 | 2122 | if connResult: 2123 | info('lastBlock sent [' + hosts + ']') 2124 | 2125 | else: 2126 | debug('[' + hosts + '] Connection Error !') 2127 | 2128 | # If chain has only genesis block 2129 | else: 2130 | info('Blockchain has only genesis block.') 2131 | 2132 | else: 2133 | debug('Database name does not found!') 2134 | 2135 | # Create collection and genesis 2136 | genesis_creation() 2137 | collection = db.blocks 2138 | # noinspection PyUnusedLocal 2139 | cursor = collection.find() 2140 | 2141 | # Call it again to get more info 2142 | databaseExists() 2143 | 2144 | 2145 | # Calculate genesis block hash value 2146 | def genesisHash(): 2147 | calcHash = '' 2148 | for heads in header_of_block: 2149 | if heads != 'hash' and heads != 'totalHash' and \ 2150 | heads != 'who' and heads != 'message': 2151 | item = SHA512.new(str(0).encode(utf_type)).hexdigest() 2152 | calcHash = SHA512.new(str(calcHash).encode(utf_type) + str(item).encode(utf_type)).hexdigest() 2153 | 2154 | newHash = SHA512.new(str(calcHash).encode(utf_type) + str(code_block_07).encode(utf_type)).hexdigest() 2155 | 2156 | return newHash 2157 | 2158 | 2159 | # Build a genesis block with 0 2160 | def genesis_creation(): 2161 | global blockid_curr, prevhash_curr, phash_curr, last_idcurr 2162 | 2163 | genZero = SHA512.new(str(0).encode(utf_type)).hexdigest() 2164 | genMSG = SHA512.new(str("It's the genesis block.").encode(utf_type)).hexdigest() 2165 | genHash = genesisHash() 2166 | 2167 | db.blocks.insert({ 2168 | "blockID" : 0 , 2169 | "senderID" : genZero , 2170 | "receiverID" : genZero , 2171 | "message" : genMSG , 2172 | "timestamp" : genZero , 2173 | "hash" : genHash , 2174 | "prevHash" : genZero , 2175 | "digitalSignature" : genZero , 2176 | "verKey" : genZero , 2177 | "nonce" : genZero , 2178 | "who" : genZero , 2179 | "totalHash" : genZero 2180 | }) 2181 | info('Genesis block generated.') 2182 | 2183 | 2184 | # Save UUID.. 2185 | def save_uuid(peer_uuid): 2186 | if isfile(uuid_path): 2187 | file = open(uuid_path, 'a') 2188 | file.write(str(peer_uuid) + '\n') 2189 | file.close() 2190 | else: 2191 | system('touch ' + str(uuid_path)) 2192 | 2193 | 2194 | # Control Qtimer to detect unused blocks in the Queue 2195 | def control_engineueue(): 2196 | while True: 2197 | if int(queue_verifytimer.qsize()) != 0: 2198 | for size in range(0, int(queue_verifytimer.qsize())): 2199 | timer = queue_verifytimer.get() 2200 | timer -= 1 2201 | 2202 | # Time is OUT 2203 | if timer <= 0: 2204 | get_from_queue(queue_verify) 2205 | 2206 | else: 2207 | try: 2208 | queue_verifytimer.put(timer) 2209 | except: 2210 | queue_verifytimer.get() 2211 | try: 2212 | queue_verifytimer.put(timer) 2213 | except: 2214 | pass 2215 | 2216 | if int(queue_conftimer.qsize()) != 0: 2217 | for size in range(0, int(queue_conftimer.qsize())): 2218 | timerC = queue_conftimer.get() 2219 | timerC -= 1 2220 | 2221 | # Time is OUT 2222 | if timerC <= 0: 2223 | get_from_queue(queue_conf) 2224 | 2225 | else: 2226 | try: 2227 | queue_conftimer.put(timerC) 2228 | except: 2229 | queue_conftimer.get() 2230 | try: 2231 | queue_conftimer.put(timerC) 2232 | except: 2233 | pass 2234 | 2235 | sleep(15) 2236 | 2237 | 2238 | # Calculate and find blockhash(es) 2239 | def calcandfind(): 2240 | while True: 2241 | if int(queue_block_who.qsize()) >= 499: 2242 | sleep(15) 2243 | 2244 | else: 2245 | who = generate_block_hash() 2246 | try: 2247 | queue_block_who.put(who) 2248 | except: 2249 | if int(queue_block_who.qsize()) != 0: 2250 | queue_block_who.get() 2251 | try: 2252 | queue_block_who.put(who) 2253 | except: 2254 | pass 2255 | 2256 | 2257 | def engine_starts(): 2258 | global shared_pairs 2259 | shared_pairs = 0 2260 | 2261 | # Generate blockWho 2262 | blockWhogen = Process(target=calcandfind, ) 2263 | blockWhogen.start() 2264 | sleep(0.05) 2265 | 2266 | # Generate blockWho 2267 | blockWhogen2 = Process(target=calcandfind, ) 2268 | blockWhogen2.start() 2269 | sleep(0.5) 2270 | 2271 | # Create a listening server 2272 | listenConn = Thread(target=Conn, ) 2273 | listenConn.start() 2274 | sleep(0.5) 2275 | 2276 | # Generate an elliptic curve object 2277 | global ecdh_obj 2278 | ecdh_obj = elliptic_pair() 2279 | 2280 | my_uuid = input('UUID:') 2281 | global hash_uuid 2282 | hash_uuid = SHA512.new(my_uuid.encode(utf_type)).hexdigest().encode(utf_type) 2283 | 2284 | connect(auth_host, ecdh_obj.serialized_public + hash_uuid) 2285 | 2286 | while True: 2287 | if len(codes_of_block) == 13: 2288 | break 2289 | 2290 | 2291 | def main(): 2292 | # MongoDB Process... 2293 | mongodbProc = Thread(target=mongo_service, ) 2294 | mongodbProc.start() 2295 | sleep(1) 2296 | 2297 | global blockid_curr, prevhash_curr, phash_curr, last_idcurr 2298 | # Get last block informations in MongoDB 2299 | lastB = getlastBlock() 2300 | blockid_curr = int(lastB.blockID) 2301 | prevhash_curr = lastB.hash 2302 | phash_curr = lastB.prevHash 2303 | last_idcurr = lastB._id 2304 | 2305 | # Chain Operations... 2306 | chain_engine = Thread(target=chain_operations, ) 2307 | chain_engine.start() 2308 | sleep(0.5) 2309 | 2310 | # User Operations... 2311 | user_engine = Thread(target=user_operations, ) 2312 | user_engine.start() 2313 | sleep(0.5) 2314 | 2315 | # Miner Operations... 2316 | miner_engine = Thread(target=miner_operations, ) 2317 | miner_engine.start() 2318 | sleep(0.5) 2319 | 2320 | # Control confirmation queue Operations... 2321 | control_engine = Thread(target=check_queue, ) 2322 | control_engine.start() 2323 | sleep(0.5) 2324 | 2325 | 2326 | # When the program starts... 2327 | def engine(): 2328 | global code_block_00, code_block_01, code_block_02, code_block_03 2329 | global code_block_04, code_block_05, code_block_06, code_block_07 2330 | global code_block_08, code_block_09, code_block_10, code_block_11 2331 | global code_block_11, code_block_12 2332 | 2333 | startLog() 2334 | sleep(0.01) 2335 | info('main() function is called.' ) 2336 | info('Queue for IP is created.' ) 2337 | info('Queue for Conf is created.' ) 2338 | info('Queue for Verifying is created.' ) 2339 | info('Binding address is [' + binding_address + ']' ) 2340 | info('Port number is [' + str(port_number) + ']' ) 2341 | engine_starts() 2342 | main() 2343 | 2344 | 2345 | if __name__ == '__main__': 2346 | try: 2347 | # engine is activated. 2348 | engine() 2349 | 2350 | except KeyboardInterrupt: 2351 | debug('Keyboard Interrupt is occured!') 2352 | quitLog() 2353 | system("pkill -9 python") 2354 | 2355 | except AttributeError: 2356 | debug('Attribute Error: ' + str(AttributeError.__doc__)) 2357 | quitLog() 2358 | exit() 2359 | 2360 | except (KeyboardInterrupt, EOFError): 2361 | debug('KeyboardInterrupt or EOFError !') 2362 | quitLog() 2363 | exit() 2364 | 2365 | except: 2366 | debug('Something was wrong..!') 2367 | quitLog() 2368 | exit() 2369 | -------------------------------------------------------------------------------- /mining_part.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | ################################################ 4 | # EMRE OVUNC # 5 | ################################################ 6 | # info@emreovunc.com # 7 | ################################################ 8 | # MINING PART # 9 | ################################################ 10 | 11 | import ssl 12 | from sys import exit 13 | from time import sleep 14 | from json import JSONEncoder 15 | from json import dumps 16 | from json import loads 17 | from queue import Queue 18 | from pickle import dumps as d0 19 | from pickle import loads as l0 20 | from random import randint 21 | from random import choice 22 | from socket import socket 23 | from socket import AF_INET 24 | from socket import SOCK_STREAM 25 | from socket import SOL_SOCKET 26 | from socket import SO_REUSEADDR 27 | from base64 import b64encode 28 | from base64 import b64decode 29 | from string import digits 30 | from string import ascii_lowercase 31 | from string import ascii_uppercase 32 | from logging import warning 33 | from logging import info 34 | from logging import debug 35 | from logging import basicConfig 36 | from logging import DEBUG 37 | from datetime import datetime as dt 38 | from threading import Thread 39 | from threading import Lock 40 | from Crypto.Hash import SHA512 41 | from bson.objectid import ObjectId 42 | from multiprocessing import Process 43 | from multiprocessing import Manager 44 | from cryptography.hazmat.backends import default_backend 45 | from cryptography.hazmat.primitives import hashes 46 | from cryptography.hazmat.primitives import serialization 47 | from cryptography.hazmat.primitives.ciphers import modes 48 | from cryptography.hazmat.primitives.ciphers import Cipher 49 | from cryptography.hazmat.primitives.ciphers import algorithms 50 | from cryptography.hazmat.primitives.kdf.hkdf import HKDF 51 | from cryptography.hazmat.primitives.asymmetric import ec 52 | 53 | # Logging configuration 54 | basicConfig(filename = 'eo_miningpart.log', 55 | level = DEBUG, 56 | format = '%(asctime)s : %(levelname)s : %(message)s', 57 | datefmt = '%m/%d/%Y %I:%M:%S %p') 58 | 59 | # Connection informations 60 | current_address = "X" 61 | binding_address = "127.0.0.1" 62 | hosts_of_chains = ["Y", "Z"] 63 | auth_server = 'T' 64 | mining_hosts = [] 65 | chain_port = 55555 66 | user_port = 31313 67 | user_message = 44444 68 | 69 | # Multi-threading 70 | miner_thread_lock = Lock() 71 | user_thread_lock = Lock() 72 | 73 | # Multi-processing 74 | manager = Manager() 75 | queue_block_whom = manager.Queue(maxsize=500) 76 | queue_user_whom = manager.Queue(maxsize=500) 77 | queue_proofofwork = manager.Queue(maxsize=2) 78 | 79 | # Block headers 80 | header_of_block = 81 | [ 82 | 'senderID' , 'receiverID', 'message' , 'timestamp', 83 | 'digitalSignature', 'verKey' , 'prevHash' , '_id' , 84 | 'hash' , 'who' , 'totalHash', 'blockID' , 85 | 'nonce' 86 | ] 87 | 88 | # Block.ok and NoK objects 89 | block_ok_obj = [] 90 | block_previd_obj = [] 91 | 92 | # Encoding & Decoding type 93 | utf_type = 'utf-8' 94 | 95 | # Defaults 96 | blockID = '0' 97 | prevHash = '0' 98 | blockid_end = '0' 99 | qF = 8080 100 | qOUT = 0 101 | 102 | # Queue(s) 103 | queue_chain = Queue(maxsize=500) 104 | queue_user = Queue(maxsize=500) 105 | queue_verify = Queue(maxsize=500) 106 | queue_fakeblock = Queue(maxsize=500) 107 | 108 | # Queue timeout 30 seconds for each item 109 | queue_timeout = 30 110 | 111 | # Temp. Queues 112 | temp_hash_q = Queue(maxsize=500) 113 | temp_hash_q_2 = Queue(maxsize=500) 114 | 115 | # Block Communication Codes 116 | codes_of_block = [] 117 | 118 | # Other's Public 119 | public_storage = [] 120 | 121 | # 0 for Block is NoK 122 | # 1 for Block is OK 123 | # 2 for Hash is NoK 124 | # 3 for Hash is OK 125 | # 4 for lastBlock is NoK 126 | # 5 for lastBlock is OK 127 | # 6 for lastBlock Request 128 | # 7 for Database add 129 | # 8 for User NoK 130 | # 9 for User OK 131 | # 10 for User Request 132 | # 11 for Block values request 133 | # 12 for Send your blocks 134 | 135 | # Converter flag to check block hash 136 | flag_converter = 0 137 | 138 | 139 | # Block ok and NoK values calculation 140 | class block_ok_nok_objs: 141 | def __init__(self, hash, ok, NoK, IP): 142 | info('block_ok_nok_objs object is created.') 143 | self.hash = hash 144 | self.ok = ok 145 | self.NoK = NoK 146 | self.IP = [] 147 | self.IP.append(IP) 148 | 149 | 150 | # prevHash and blockID values 151 | class block_prev_id: 152 | def __init__(self, hash, prevHash, blockID, counter, IP): 153 | self.prevHash = [] 154 | self.blockID = [] 155 | self.IP = [] 156 | self.counter = [] 157 | self.hash = hash 158 | if prevHash != 0: 159 | self.prevHash.append(prevHash) 160 | if blockID != 0: 161 | self.blockID.append(blockID) 162 | if IP != 0: 163 | self.IP.append(IP) 164 | if counter != 0: 165 | self.counter.append(counter) 166 | 167 | 168 | # Sign the block 169 | def sign_block(Block): 170 | Block.verKey = b64encode(ecdh_obj.sign_message(Block.totalHash)).decode("ISO-8859-1") 171 | 172 | 173 | def quitLog(): 174 | warning('----------------------------------------') 175 | warning('----- Mining Server is stopping... -----') 176 | warning('----------------------------------------') 177 | 178 | 179 | def startLog(): 180 | warning('++++++++++++++++++++++++++++++++++++++++') 181 | warning('+++++ Mining Server is starting... +++++') 182 | warning('++++++++++++++++++++++++++++++++++++++++') 183 | 184 | 185 | # Encoder class for mongodb blocks 186 | class Encoder(JSONEncoder): 187 | def default(self, obj): 188 | if isinstance(obj, ObjectId): 189 | return str(obj) 190 | 191 | else: 192 | return obj 193 | 194 | 195 | # Decoder func. for receiving mongodb blocks 196 | def decoder(dct): 197 | for k, v in dct.items(): 198 | if '_id' in dct: 199 | try: 200 | dct['_id'] = ObjectId(dct['_id']) 201 | except: 202 | pass 203 | return dct 204 | 205 | 206 | # Get current time 207 | def get_current_time(): 208 | now = dt.now() 209 | time = now.isoformat() 210 | return time 211 | 212 | 213 | def dumpRecv(object): 214 | return dumps(object) 215 | 216 | 217 | def loadRecv(object): 218 | return loads(object) 219 | 220 | 221 | # Queue Function for putting 222 | def qPut(q, data): 223 | try: 224 | q.put(data, timeout=queue_timeout) 225 | except: 226 | qGet(q) 227 | try: 228 | q.put(data, timeout=queue_timeout) 229 | except: 230 | pass 231 | 232 | 233 | # Queue Function for getting 234 | def qGet(q): 235 | try: 236 | if int(q.qsize()) != 0: 237 | return q.get() 238 | except: 239 | return 0 240 | 241 | 242 | # Queue Function for queue size 243 | def qSize(q): 244 | return int(q.qsize()) 245 | 246 | 247 | # Elliptic curve key-pairs 248 | class elliptic_pair: 249 | def __init__(self): 250 | # Generate a private key for use in the exchange. 251 | self.private_key = ec.generate_private_key(ec.SECT571K1, default_backend()) 252 | self.public_key = self.private_key.public_key() 253 | 254 | # Serialization of Public Key 255 | self.serialized_public = self.public_key.public_bytes( 256 | encoding = serialization.Encoding.PEM, 257 | format = serialization.PublicFormat.SubjectPublicKeyInfo) 258 | 259 | # To find shared secret using user's private and other's public 260 | def findsharedKEY(self, peer_public): 261 | shared_key = self.private_key.exchange(ec.ECDH(), peer_public) 262 | return shared_key 263 | 264 | # Serialize and save private key 265 | def __serialize_private(self): 266 | __serialized_private = self.private_key.private_bytes( 267 | encoding = serialization.Encoding.PEM, 268 | format = serialization.PrivateFormat.PKCS8, 269 | encryption_algorithm = serialization.BestAvailableEncryption(bytes(codes_of_block[0]))) 270 | 271 | # Signing the message 272 | def sign_message(self, message): 273 | message = message.encode(utf_type) 274 | sign = self.private_key.sign(message, ec.ECDSA(hashes.SHA256())) 275 | return sign 276 | 277 | @staticmethod 278 | # Verifying the message 279 | def verify_message(public_key, message, sign): 280 | try: 281 | sign = b64decode(sign).encode("ISO-8859-1") 282 | except: 283 | sign = b64decode(sign) 284 | message = message.encode(utf_type) 285 | return public_key.verify(sign, message, ec.ECDSA(hashes.SHA256())) 286 | 287 | 288 | # De-serialization of Public Key 289 | def deserialize_pubkey(peer_public): 290 | loaded_public_key = serialization.load_pem_public_key( 291 | peer_public, 292 | backend = default_backend()) 293 | return loaded_public_key 294 | 295 | 296 | # Serialization of Public Keys 297 | def serialize_pubkey(publickey): 298 | serialized_public = publickey.public_bytes( 299 | encoding = serialization.Encoding.PEM, 300 | format = serialization.PublicFormat.SubjectPublicKeyInfo) 301 | return serialized_public 302 | 303 | 304 | # HMAC-based Extract and Expand Key Derivation Function 305 | def derivation_keys(shared_key): 306 | hkdf = HKDF( 307 | algorithm = hashes.SHA256() , 308 | length = 32 , 309 | salt = shared_key[16:32], 310 | info = shared_key[:16] , 311 | backend = default_backend()) 312 | 313 | keyDerived = hkdf.derive(shared_key[16:]) 314 | return keyDerived 315 | 316 | 317 | # AES Encryption Part 318 | def aes_encryption_func(keyDerived, shared_key, message): 319 | if not type(message) == bytes: 320 | message = message.encode(utf_type) 321 | 322 | if not type(shared_key) == bytes: 323 | shared_key = shared_key.encode(utf_type) 324 | 325 | if not type(keyDerived) == bytes: 326 | keyDerived = keyDerived.encode(utf_type) 327 | 328 | length = 16 - (len(message) % 16) 329 | message += bytes([length]) * length 330 | backend = default_backend() 331 | key = keyDerived 332 | iv = shared_key[:16] 333 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 334 | encryptor = cipher.encryptor() 335 | encrypted = encryptor.update(message) + encryptor.finalize() 336 | 337 | return encrypted 338 | 339 | 340 | # AES Decryption Part 341 | def aes_decryption_func(keyDerived, shared_key, message): 342 | if not type(message) == bytes: 343 | message = message.encode(utf_type) 344 | 345 | if not type(shared_key) == bytes: 346 | shared_key = shared_key.encode(utf_type) 347 | 348 | if not type(keyDerived) == bytes: 349 | keyDerived = keyDerived.encode(utf_type) 350 | 351 | backend = default_backend() 352 | key = keyDerived 353 | iv = shared_key[:16] 354 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 355 | decryptor = cipher.decryptor() 356 | dt = decryptor.update(message) + decryptor.finalize() 357 | decrypted = dt[:-dt[-1]].decode(utf_type) 358 | 359 | return decrypted 360 | 361 | 362 | def engine_starts(): 363 | # Create a listening server for Blockchain Server 364 | listenConn = Thread(target=listen_all_chain_conns, ) 365 | listenConn.start() 366 | sleep(0.5) 367 | 368 | # Generate blockWho for miner 369 | blockWhomin = Process(target=block_who_miner_func, ) 370 | blockWhomin.start() 371 | sleep(0.05) 372 | 373 | # Generate blockWho for miner 374 | blockWhomin2 = Process(target=block_who_miner_func, ) 375 | blockWhomin2.start() 376 | sleep(0.05) 377 | 378 | # Generate blockWho for user 379 | blockWhousr = Process(target=block_who_user_func, ) 380 | blockWhousr.start() 381 | sleep(0.05) 382 | 383 | # Generate blockWho for user 384 | blockWhousr2 = Process(target=block_who_user_func, ) 385 | blockWhousr2.start() 386 | sleep(0.05) 387 | 388 | global shared_pairs 389 | shared_pairs = 0 390 | 391 | # Generate an elliptic curve object 392 | global ecdh_obj 393 | ecdh_obj = elliptic_pair() 394 | 395 | my_uuid = input('UUID:') 396 | global hash_uuid 397 | hash_uuid = SHA512.new(my_uuid.encode(utf_type)).hexdigest().encode(utf_type) 398 | 399 | connect(auth_server, ecdh_obj.serialized_public + hash_uuid) 400 | 401 | while True: 402 | if len(codes_of_block) == 13: 403 | break 404 | 405 | 406 | # When the program starts... 407 | def engine_func(): 408 | global blockCode00, blockCode01, blockCode02, blockCode03 409 | global blockCode04, blockCode05, blockCode06, blockCode07 410 | global blockCode08, blockCode09, blockCode10, blockCode11 411 | global blockCode11, blockCode12 412 | 413 | startLog() 414 | info('User Binding address is [' + str(current_address) + ']') 415 | info('Binding address is [' + str(binding_address) + ']') 416 | info('Chain Port number is [' + str(chain_port) + ']') 417 | info('User Port number is [' + str(user_port) + ']') 418 | info('User MSG Port number is [' + str(user_message) + ']') 419 | info('Queue for "User" is created.' ) 420 | info('Queue for "Verify" is created.' ) 421 | info('Queue for "Chain" is created.' ) 422 | info('main() function is started.' ) 423 | engine_starts() 424 | main() 425 | 426 | 427 | def conv_mod_10(hex): 428 | if hex == 'a': 429 | return 0 430 | 431 | elif hex == 'b': 432 | return 1 433 | 434 | elif hex == 'c': 435 | return 2 436 | 437 | elif hex == 'd': 438 | return 3 439 | 440 | elif hex == 'e': 441 | return 4 442 | 443 | elif hex == 'f': 444 | return 5 445 | 446 | else: 447 | return hex 448 | 449 | 450 | def conv_mod_16(nmbr): 451 | if int(nmbr) == 0: 452 | return 'a' 453 | 454 | elif int(nmbr) == 1: 455 | return 'b' 456 | 457 | elif int(nmbr) == 2: 458 | return 'c' 459 | 460 | elif int(nmbr) == 3: 461 | return 'd' 462 | 463 | elif int(nmbr) == 4: 464 | return 'e' 465 | 466 | elif int(nmbr) == 5: 467 | return 'f' 468 | 469 | else: 470 | return nmbr 471 | 472 | 473 | # Convert dict to object 474 | class obj(object): 475 | def __init__(self, d): 476 | 477 | for a, b in d.items(): 478 | 479 | if isinstance(b, (list, tuple)): 480 | setattr(self, a, [obj(x) if isinstance(x, dict) else x for x in b]) 481 | 482 | else: 483 | setattr(self, a, obj(b) if isinstance(b, dict) else b) 484 | 485 | 486 | # Dump object before sending 487 | def dumping_object(object): 488 | info('The object is dumping..') 489 | return dumps(object) 490 | 491 | 492 | # Load received object 493 | def loading_object(object): 494 | info('The object is loading..') 495 | return loads(object) 496 | 497 | 498 | # Find and return block_ok_nok_objs object 499 | def found_block_ok_objs(blockHash, IPAdd, type): 500 | if type == 0: 501 | for calcs in block_ok_obj: 502 | if calcs.hash == blockHash: 503 | info('Calc0bj already created.!') 504 | return calcs, 1 505 | 506 | info('Calc0bj is appending...') 507 | block_ok_obj.append(block_ok_nok_objs(blockHash, 0, 0, IPAdd)) 508 | return block_ok_obj[-1], 0 509 | 510 | elif type == 2: 511 | IPf = 0 512 | 513 | if len(block_previd_obj) > 15: 514 | block_previd_obj.remove(block_previd_obj[0]) 515 | 516 | for objs in block_previd_obj: 517 | if objs.hash == blockHash: 518 | 519 | for IPs in objs.IP: 520 | if IPs == IPAdd: 521 | IPf += 1 522 | 523 | if IPf == 0: 524 | info('IP is appending..!') 525 | objs.IP.append(IPAdd) 526 | 527 | if len(block_ok_obj) > 10: 528 | block_ok_obj.remove(block_ok_obj[0]) 529 | 530 | return objs 531 | 532 | else: 533 | return 1 534 | 535 | return 2 536 | 537 | 538 | # Find and remove block_ok_nok_objs object 539 | def remove_block_ok_objs(blockHash): 540 | for calcs in block_ok_obj: 541 | if calcs.hash == blockHash: 542 | info('Calc0bj is deleted!') 543 | block_ok_obj.remove(calcs) 544 | del calcs 545 | break 546 | 547 | 548 | # Convert parts to decimal 549 | def conv_10(part): 550 | # If part has one string 551 | if len(str(part)) == 1: 552 | part = conv_mod_10(part) 553 | 554 | # If part has more strings 555 | elif len(str(part)) == 2: 556 | try: 557 | part1 = int(part[0]) 558 | except: 559 | part1 = conv_mod_10(part[0]) 560 | 561 | try: 562 | part2 = int(part[1]) 563 | except: 564 | part2 = conv_mod_10(part[1]) 565 | 566 | part = str(part1) + str(part2) 567 | 568 | # If part becomes an ERROR 569 | else: 570 | debug('conv_10() string ERROR!') 571 | 572 | return int(part) 573 | 574 | 575 | # Convert parts to hexadecimal 576 | def conv_16(part): 577 | addPart = [] 578 | for parts in part: 579 | # If parts have one digit 580 | if len(str(parts)) == 1: 581 | 582 | chance = randint(0, 1) 583 | if chance == 1: 584 | addPart.append('0' + str(conv_mod_16(parts))) 585 | 586 | else: 587 | addPart.append('0' + str(parts)) 588 | 589 | # If parts have two digits. 590 | elif len(str(parts)) == 2: 591 | parts = str(parts) 592 | 593 | chance = randint(0, 1) 594 | if chance == 1: 595 | x = conv_mod_16(parts[0]) 596 | 597 | else: 598 | x = parts[0] 599 | 600 | chance = randint(0, 1) 601 | if chance == 1: 602 | y = conv_mod_16(parts[1]) 603 | 604 | else: 605 | y = parts[1] 606 | 607 | addPart.append(str(x) + str(y)) 608 | 609 | # If parts have three digits 610 | else: 611 | parts = str(parts) 612 | 613 | chance = randint(0, 1) 614 | if chance == 1: 615 | x = conv_mod_16(parts[0]) 616 | 617 | else: 618 | x = parts[0] 619 | 620 | chance = randint(0, 1) 621 | if chance == 1: 622 | y = conv_mod_16(parts[1]) 623 | 624 | else: 625 | y = parts[0] 626 | 627 | chance = randint(0, 1) 628 | if chance == 1: 629 | z = conv_mod_16(parts[2]) 630 | 631 | else: 632 | z = parts[2] 633 | 634 | addPart.append(str(x) + str(y) + str(z)) 635 | 636 | return addPart 637 | 638 | 639 | # Find blockID from the hash value 640 | def found_blockid_hash(Hash): 641 | info('Finding blockID ...') 642 | global blockid_end 643 | 644 | # If blockID is same as lastBlockID + 1 645 | if Hash == SHA512.new(str(int(blockid_end) + 1).encode(utf_type)).hexdigest(): 646 | 647 | # Return new blockID value 648 | info('blockID is found by using lastBlockID!') 649 | blockid_end = int(blockid_end) + 1 650 | 651 | return int(blockid_end) 652 | 653 | if 0 < int(blockid_end) - 10: 654 | 655 | for IDs in range(blockid_end - 10 , blockid_end + 10): 656 | 657 | # Controlling.. 658 | if Hash == SHA512.new(str(IDs).encode(utf_type)).hexdigest(): 659 | 660 | # Return new blockID value 661 | info('blockID is found range of lastBlockID!') 662 | blockid_end = int(IDs) 663 | 664 | return int(IDs) 665 | 666 | # Calculation all values... 667 | # It takes some time... 668 | IDs = 100 669 | while True: 670 | 671 | # If blockID does NOT found, extend the range... 672 | for IDs in range(IDs - 100, IDs + 100): 673 | 674 | # Controlling.. 675 | if Hash == SHA512.new(str(IDs).encode(utf_type)).hexdigest(): 676 | 677 | # Return new blockID value 678 | info('blockID is found by bruteforcing..!') 679 | blockid_end = int(IDs) 680 | 681 | return int(IDs) 682 | 683 | # Increase range area 684 | IDs += 100 685 | 686 | 687 | # Generate mining side hash.. 688 | def generate_mining_hash(): 689 | while True: 690 | part = [randint(0, 99), randint(0, 99), 691 | randint(0, 99), randint(0, 99), 692 | randint(1, 99), randint(1, 99)] 693 | 694 | if part[0] != part[1] and part[1] != part[2] and part[2] != part[3] and\ 695 | part[3] != part[4] and part[4] != part[5] and part[0] != part[2] and\ 696 | part[0] != part[3] and part[0] != part[4] and part[4] != part[5] and\ 697 | part[1] != part[3] and part[1] != part[4] and part[1] != part[5] and\ 698 | part[2] != part[4] and part[2] != part[5] and part[3] != part[5]: 699 | hexPart = conv_16(part) 700 | 701 | number = randint(0, 128) 702 | n = "" 703 | 704 | for iteration in range(0, number): 705 | n = choice(digits) + str(number) + choice(ascii_lowercase) + choice(ascii_uppercase) + n 706 | 707 | myHash = SHA512.new(str(n).encode(utf_type)).hexdigest() 708 | newHash = '' 709 | 710 | if myHash.startswith('0'): 711 | 712 | try: 713 | item1 = int(myHash[part[0]]) % 10 714 | except ValueError: 715 | item1 = conv_mod_10(myHash[part[0]]) 716 | 717 | try: 718 | item2 = int(myHash[part[1]]) % 10 719 | except ValueError: 720 | item2 = conv_mod_10(myHash[part[1]]) 721 | 722 | try: 723 | item3 = int(myHash[part[2]]) % 10 724 | except ValueError: 725 | item3 = conv_mod_10(myHash[part[2]]) 726 | 727 | if int(item1) != int(item2): 728 | 729 | if int(item1) != int(item3): 730 | 731 | if int(item1) + int(item2) % 10 == int(item3): 732 | 733 | try: 734 | item4 = int(myHash[part[3]]) % 10 735 | except ValueError: 736 | item4 = conv_mod_10(myHash[part[3]]) 737 | 738 | try: 739 | item5 = int(myHash[part[4]]) % 10 740 | except: 741 | item5 = conv_mod_10(myHash[part[4]]) 742 | 743 | if int(item4) == int(item5): 744 | 745 | if (int(item1) + int(item3)) % 10 == int(item5): 746 | 747 | try: 748 | shifting = int(myHash[part[5]]) % 10 749 | except: 750 | shifting = conv_mod_10(myHash[part[5]]) 751 | 752 | flg = shifting 753 | 754 | if int(shifting) != 0: 755 | 756 | for times in range(0, int(shifting)): 757 | sftHash = '' 758 | temp = myHash[0] 759 | 760 | for item in range(1, int(len(myHash))): 761 | 762 | try: 763 | sftHash += myHash[item] 764 | except IndexError: 765 | pass 766 | 767 | sftHash += temp 768 | myHash = sftHash 769 | newHash = myHash 770 | 771 | for hexs in hexPart: 772 | newHash = hexs + newHash 773 | 774 | return newHash + str(flg) 775 | 776 | else: 777 | 778 | for hexs in hexPart: 779 | myHash = hexs + myHash 780 | 781 | return myHash + str(flg) 782 | 783 | 784 | # Generate user side hash.. 785 | def generate_user_hash(): 786 | while True: 787 | part = [randint(0, 99), randint(0, 99), 788 | randint(0, 99), randint(0, 99), 789 | randint(0, 99), randint(0, 99)] 790 | 791 | if part[0] != part[1] and part[1] != part[2] and part[2] != part[3] and\ 792 | part[3] != part[4] and part[4] != part[5] and part[0] != part[2] and\ 793 | part[0] != part[3] and part[0] != part[4] and part[4] != part[5] and\ 794 | part[1] != part[3] and part[1] != part[4] and part[1] != part[5] and\ 795 | part[2] != part[4] and part[2] != part[5] and part[3] != part[5]: 796 | hexPart = conv_16(part) 797 | break 798 | 799 | while True: 800 | 801 | number = randint(0, 128) 802 | n = "" 803 | 804 | for iteration in range(0, number): 805 | n = choice(digits) + str(number) + choice(ascii_lowercase) + choice(ascii_uppercase) + n 806 | 807 | myHash = SHA512.new(str(n).encode(utf_type)).hexdigest() 808 | newHash = '' 809 | 810 | if myHash.startswith('0'): 811 | 812 | try: 813 | item1 = int(myHash[part[0]]) % 10 814 | except ValueError: 815 | item1 = conv_mod_10(myHash[part[0]]) 816 | 817 | try: 818 | item2 = int(myHash[part[1]]) % 10 819 | except ValueError: 820 | item2 = conv_mod_10(myHash[part[1]]) 821 | 822 | try: 823 | item3 = int(myHash[part[2]]) % 10 824 | except ValueError: 825 | item3 = conv_mod_10(myHash[part[2]]) 826 | 827 | if int(item1) + int(item2) % 10 != int(item3): 828 | 829 | if int(item1) != int(item3): 830 | 831 | if int(item1) == int(item2): 832 | 833 | try: 834 | item4 = int(myHash[part[3]]) % 10 835 | except ValueError: 836 | item4 = conv_mod_10(myHash[part[3]]) 837 | 838 | if int(item3) == int(item4): 839 | 840 | try: 841 | item5 = int(myHash[part[4]]) % 10 842 | except: 843 | item5 = conv_mod_10(myHash[part[4]]) 844 | 845 | if (int(item1) + int(item3)) % 10 == int(item5): 846 | 847 | try: 848 | shifting = int(myHash[part[5]]) % 10 849 | except: 850 | shifting = conv_mod_10(myHash[part[5]]) 851 | 852 | flg = shifting 853 | 854 | if int(shifting) != 0: 855 | 856 | for times in range(0, int(shifting)): 857 | sftHash = '' 858 | temp = myHash[0] 859 | 860 | for item in range(1, int(len(myHash))): 861 | 862 | try: 863 | sftHash += myHash[item] 864 | except IndexError: 865 | pass 866 | 867 | sftHash += temp 868 | myHash = sftHash 869 | newHash = myHash 870 | 871 | for hexs in hexPart: 872 | newHash = hexs + newHash 873 | 874 | return newHash + str(flg) 875 | 876 | else: 877 | 878 | for hexs in hexPart: 879 | myHash = hexs + myHash 880 | 881 | return myHash + str(flg) 882 | 883 | 884 | # CLIENT SIDE 885 | # Send a block to others 886 | def connect(HOST, message): 887 | info('Message is sending to [' + str(HOST) + ']') 888 | 889 | # Byte shifting values.. 890 | try: 891 | mySocket = socket(AF_INET, SOCK_STREAM) 892 | mySocket.settimeout(2) 893 | context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH) 894 | context.check_hostname = False 895 | context.load_cert_chain('selfsigned.cert', 'selfsigned.key') 896 | context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 897 | conn = context.wrap_socket(mySocket) 898 | conn.connect((HOST, chain_port)) 899 | 900 | # Sending bytes data.. 901 | if type(message) == bytes: 902 | info('Sending bytes format..') 903 | conn.send(message) 904 | 905 | # '.obj' in str(type(message)) 906 | else: 907 | 908 | info('Sending obj or string format..') 909 | 910 | try: 911 | msg = dumps(message.__dict__) 912 | except: 913 | 914 | try: 915 | msg = dumps(message.__dict__, cls=Encoder) 916 | 917 | except: 918 | 919 | try: 920 | msg = d0(message) 921 | 922 | except: 923 | conn.close() 924 | return False 925 | 926 | try: 927 | conn.send(d0(msg.encode("ISO-8859-1"))) 928 | 929 | except: 930 | 931 | try: 932 | conn.send(msg) 933 | 934 | except: 935 | return False 936 | 937 | info('Message is sent to [' + str(HOST) + ']') 938 | conn.close() 939 | 940 | return True 941 | 942 | except ConnectionRefusedError: 943 | debug('Receiver [' + str(HOST) + '] is OFFLINE!') 944 | return False 945 | 946 | except: 947 | debug('Receiver [' + str(HOST) + '] seems like OFFLINE!') 948 | return False 949 | 950 | 951 | # USER LOCAL SIDE 952 | # Send some messages 953 | def userConnect(message): 954 | info('connect() function called.') 955 | 956 | # Byte shifting values.. 957 | try: 958 | mySocket = socket(AF_INET, SOCK_STREAM) 959 | mySocket.connect((binding_address, user_message)) 960 | 961 | # Sending bytes data.. 962 | if type(message) == bytes: 963 | info('Sending bytes format..') 964 | mySocket.send(message) 965 | 966 | # '.obj' in str(type(message)) 967 | else: 968 | info('Sending obj or string format..') 969 | 970 | try: 971 | msg = dumps(message.__dict__) 972 | except: 973 | try: 974 | msg = dumps(message.__dict__, cls=Encoder) 975 | except: 976 | if 'estimatedtime' in message: 977 | msg = message 978 | else: 979 | mySocket.close() 980 | return False 981 | 982 | mySocket.send(msg.encode("ISO-8859-1")) 983 | 984 | info('Message is sent to [' + str(binding_address) + ']') 985 | mySocket.close() 986 | 987 | return True 988 | 989 | except ConnectionRefusedError: 990 | debug('Receiver [' + str(binding_address) + '] is OFFLINE!') 991 | 992 | return False 993 | 994 | except: 995 | debug('Receiver [' + str(binding_address) + '] seems like OFFLINE!') 996 | 997 | return False 998 | 999 | 1000 | # Create a merkle hash and return ROOT 1001 | def main_block(Block): 1002 | info('Merkle tree created..') 1003 | merkle = '' 1004 | 1005 | newblockID = SHA512.new(str(Block.blockID).encode(utf_type)).hexdigest() 1006 | newsenderID = SHA512.new(str(Block.senderID).encode(utf_type)).hexdigest() 1007 | newreceiverID = SHA512.new(str(Block.receiverID).encode(utf_type)).hexdigest() 1008 | newMessage = SHA512.new(str(Block.message).encode(utf_type)).hexdigest() 1009 | newTimestamp = SHA512.new(str(Block.timestamp).encode(utf_type)).hexdigest() 1010 | newDS = SHA512.new(str(Block.digitalSignature).encode(utf_type)).hexdigest() 1011 | newVerkey = SHA512.new(str(Block.verKey).encode(utf_type)).hexdigest() 1012 | newPrevHash = SHA512.new(str(Block.prevHash).encode(utf_type)).hexdigest() 1013 | 1014 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newsenderID).encode(utf_type)).hexdigest() 1015 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newreceiverID).encode(utf_type)).hexdigest() 1016 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newMessage).encode(utf_type)).hexdigest() 1017 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newTimestamp).encode(utf_type)).hexdigest() 1018 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newDS).encode(utf_type)).hexdigest() 1019 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newVerkey).encode(utf_type)).hexdigest() 1020 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newPrevHash).encode(utf_type)).hexdigest() 1021 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newblockID).encode(utf_type)).hexdigest() 1022 | root = SHA512.new(str(merkle).encode(utf_type) + str(Block.nonce).encode(utf_type)).hexdigest() 1023 | 1024 | return root 1025 | 1026 | 1027 | # Check block hash re-calculation 1028 | def controlling_hash(Block): 1029 | info('Starting block hash controls..') 1030 | 1031 | try: 1032 | global blockid_end 1033 | 1034 | # Re-Calculating total hash.. 1035 | calcHash = '' 1036 | for heads in header_of_block: 1037 | if heads != 'hash' and heads != 'totalHash' and \ 1038 | heads != 'who' and heads != 'message': 1039 | 1040 | # Get correct blockID 1041 | if heads == 'blockID': 1042 | 1043 | # If block values come 1044 | if Block.totalHash == SHA512.new(str(Block.hash).encode(utf_type) + 1045 | str(blockCode11).encode(utf_type)).hexdigest(): 1046 | 1047 | root = main_block(Block) 1048 | 1049 | if root == Block.hash and str(root).startswith('00'): 1050 | 1051 | if len(Block.__dict__) == 13: 1052 | info('Blockheader is correct.') 1053 | return True 1054 | 1055 | return False 1056 | 1057 | else: 1058 | item = blockid_end 1059 | 1060 | else: 1061 | item = getattr(Block, heads) 1062 | 1063 | calcHash = SHA512.new((calcHash + str(item)).encode(utf_type)).hexdigest() 1064 | 1065 | if heads == 'prevHash': 1066 | lastHash = calcHash 1067 | 1068 | for blockcode in codes_of_block: 1069 | newCode = SHA512.new(str(blockcode).encode(utf_type)).hexdigest() 1070 | calcHash = SHA512.new(str(Block.hash).encode(utf_type) + 1071 | str(newCode).encode(utf_type)).hexdigest() 1072 | 1073 | # If calculated hash equals to block hash 1074 | if calcHash == Block.totalHash: 1075 | info('Blockhash is verified.') 1076 | 1077 | if len(Block.__dict__) == 13: 1078 | info('Blockheader is correct.') 1079 | return True 1080 | 1081 | except: 1082 | debug('Header has something wrong!') 1083 | return False 1084 | 1085 | lastHash = SHA512.new((lastHash + str(int(blockid_end + 1))).encode(utf_type)).hexdigest() 1086 | lastHash = SHA512.new((lastHash + str(Block.nonce)).encode(utf_type)).hexdigest() 1087 | 1088 | for blockcode in codes_of_block: 1089 | newCode = SHA512.new(str(blockcode).encode(utf_type)).hexdigest() 1090 | lastHash = SHA512.new(str(Block.hash).encode(utf_type) + 1091 | str(newCode).encode(utf_type)).hexdigest() 1092 | 1093 | # If calculated hash equals to block hash 1094 | if lastHash == Block.totalHash: 1095 | info('Blockhash is verified.') 1096 | 1097 | if len(Block.__dict__) == 13: 1098 | info('Blockheader is correct.') 1099 | return True 1100 | 1101 | global blockID 1102 | 1103 | get_blockid_hash() 1104 | timer = 0 1105 | while True: 1106 | sleep(6) 1107 | if blockID == '0': 1108 | timer += 1 1109 | sleep(2) 1110 | 1111 | else: 1112 | break 1113 | 1114 | if timer % 2 == 0: 1115 | get_blockid_hash() 1116 | 1117 | blockid_end = blockID 1118 | Block.blockID = blockID 1119 | 1120 | lastHash = SHA512.new((lastHash + str(blockid_end)).encode(utf_type)).hexdigest() 1121 | lastHash = SHA512.new((lastHash + str(Block.nonce)).encode(utf_type)).hexdigest() 1122 | 1123 | for blockcode in codes_of_block: 1124 | newCode = SHA512.new(str(blockcode).encode(utf_type)).hexdigest() 1125 | lastHash = SHA512.new(str(Block.hash).encode(utf_type) + 1126 | str(newCode).encode(utf_type)).hexdigest() 1127 | 1128 | # If calculated hash equals to block hash 1129 | if lastHash == Block.totalHash: 1130 | info('Blockhash is verified.') 1131 | 1132 | if len(Block.__dict__) == 13: 1133 | info('Blockheader is correct.') 1134 | return True 1135 | 1136 | info('Blockheader is INCORRECT!') 1137 | return False 1138 | 1139 | 1140 | ### Fake Block ### 1141 | # Randoms: 1142 | # blockID 1143 | # senderID 1144 | # receiverID 1145 | # message 1146 | # timestamp 1147 | # _id 1148 | # prevHash 1149 | 1150 | # Signature: 1151 | # senderID 1152 | # receiverID 1153 | # message 1154 | # timestamp 1155 | 1156 | # Hash: 1157 | # Proof of Work 1158 | 1159 | # TotalHash: 1160 | # Hash 1161 | # BlockCodes 1162 | 1163 | # Generate a fake block 1164 | class generating_fake_block: 1165 | def __init__(self , blockID , senderID , receiverID, 1166 | message , timestamp , hash , _id , 1167 | prevHash , who , digitalSignature , verKey , 1168 | totalHash, nonce): 1169 | 1170 | # Fill values with random hash(s) 1171 | self.blockID = blockID 1172 | self.senderID = senderID 1173 | self.receiverID = receiverID 1174 | self.message = message 1175 | self.timestamp = timestamp 1176 | self.hash = hash 1177 | self._id = _id 1178 | self.prevHash = prevHash 1179 | 1180 | while True: 1181 | if queue_block_whom.qsize() != 0: 1182 | self.who = queue_block_whom.get() 1183 | break 1184 | sleep(0.05) 1185 | 1186 | signMSG = (str(self.senderID) + str(self.receiverID) + str(self.message) + str(self.timestamp)).encode(utf_type) 1187 | self.verKey = digitalSignature 1188 | self.digitalSignature = verKey 1189 | self.nonce = nonce 1190 | 1191 | newsenderID = SHA512.new(str(self.senderID).encode(utf_type)).hexdigest() 1192 | newreceiverID = SHA512.new(str(self.receiverID).encode(utf_type)).hexdigest() 1193 | newMessage = SHA512.new(str(self.message).encode(utf_type)).hexdigest() 1194 | newTimestamp = SHA512.new(str(self.timestamp).encode(utf_type)).hexdigest() 1195 | newDS = SHA512.new(str(self.digitalSignature).encode(utf_type)).hexdigest() 1196 | newVerkey = SHA512.new(str(self.verKey).encode(utf_type)).hexdigest() 1197 | 1198 | merkle = '' 1199 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newsenderID).encode(utf_type)).hexdigest() 1200 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newreceiverID).encode(utf_type)).hexdigest() 1201 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newMessage).encode(utf_type)).hexdigest() 1202 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newTimestamp).encode(utf_type)).hexdigest() 1203 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newDS).encode(utf_type)).hexdigest() 1204 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newVerkey).encode(utf_type)).hexdigest() 1205 | 1206 | quitF = 0 1207 | self.nonce = 100 1208 | # Calculate and find hash value by using little proof-of-work 1209 | while True: 1210 | for self.nonce in range(self.nonce - 100, self.nonce + 100): 1211 | 1212 | # If hash startswith '000' , Done! 1213 | if str(SHA512.new(str(merkle).encode(utf_type) + str(self.nonce).encode(utf_type)).hexdigest()).startswith('000'): 1214 | 1215 | root = SHA512.new(str(merkle).encode(utf_type) + str(self.nonce).encode(utf_type)).hexdigest() 1216 | quitF = 1 1217 | break 1218 | 1219 | # If found it, let's exit 1220 | if quitF == 1: 1221 | break 1222 | 1223 | else: 1224 | self.nonce += 100 1225 | 1226 | self.hash = root 1227 | self.totalHash = SHA512.new(str(root).encode(utf_type) + str(blockCode11).encode(utf_type)).hexdigest() 1228 | 1229 | 1230 | def gen_fake_block(): 1231 | while True: 1232 | if queue_fakeblock.qsize() >= 14: 1233 | reqHash = queue_fakeblock.get() 1234 | for objs in block_previd_obj: 1235 | if reqHash == objs.hash: 1236 | block_previd_obj.remove(objs) 1237 | del objs 1238 | break 1239 | sleep(15) 1240 | 1241 | else: 1242 | # Create a fake block object 1243 | reqBlock = generating_fake_block(randint(0, 99999999) + randint(0, 99999999), 1244 | SHA512.new(str(randint(0, 99999999) + randint(0, 99999999)).encode(utf_type)).hexdigest(), 1245 | SHA512.new(str(randint(0, 99999999) + randint(0, 99999999)).encode(utf_type)).hexdigest(), 1246 | randint(0, 99999999) + randint(0, 99999999), 1247 | get_current_time(), 1248 | SHA512.new(str(randint(0, 99999999) + randint(0, 99999999)).encode(utf_type)).hexdigest(), 1249 | SHA512.new(str(randint(0, 99999999) + randint(0, 99999999)).encode(utf_type)).hexdigest(), 1250 | randint(0, 99999999) + randint(0, 99999999), 1251 | randint(0, 99999999) + randint(0, 99999999), 1252 | SHA512.new(str(randint(0, 99999999) + randint(0, 99999999)).encode(utf_type)).hexdigest(), 1253 | SHA512.new(str(randint(0, 99999999) + randint(0, 99999999)).encode(utf_type)).hexdigest(), 1254 | randint(0, 99999999) + randint(0, 99999999), 1255 | randint(0, 99999999) + randint(0, 99999999)) 1256 | 1257 | block_previd_obj.append(block_prev_id(reqBlock.hash, 0, 0, 0, 0)) 1258 | try: 1259 | queue_fakeblock.put(reqBlock) 1260 | except: 1261 | if queue_fakeblock.qsize() != 0: 1262 | queue_fakeblock.get() 1263 | try: 1264 | queue_fakeblock.put(reqBlock) 1265 | except: 1266 | pass 1267 | 1268 | 1269 | # Get blockID & prevHash values 1270 | def get_blockid_hash(): 1271 | info('BlockValues are getting...') 1272 | while True: 1273 | if queue_fakeblock.qsize() != 0: 1274 | reqBlock = queue_fakeblock.get() 1275 | break 1276 | 1277 | for host in hosts_of_chains: 1278 | sign_block(reqBlock) 1279 | connect(host, reqBlock) 1280 | 1281 | 1282 | # Get queue time and return seconds 1283 | def queue_get_time(): 1284 | sizeofQ = 1 1285 | sizeofQ += int(qSize(queue_verify)) + int(qSize(queue_user)) 1286 | estimated = int(sizeofQ) * 25 1287 | return int(estimated) 1288 | 1289 | 1290 | # Mining operations.. 1291 | def mining_operations(): 1292 | while True: 1293 | 1294 | while True: 1295 | if int(queue_chain.qsize()) != 0: 1296 | infos = qGet(queue_chain) 1297 | block = infos[0] 1298 | IP_Add = infos[1] 1299 | break 1300 | 1301 | miner_thread_lock.acquire() 1302 | while True: 1303 | global blockID 1304 | global prevHash 1305 | 1306 | try: 1307 | if controlling_hash(block): 1308 | hashFlag = 1 1309 | 1310 | else: 1311 | info('Hash control result is FALSE!') 1312 | hashFlag = 0 1313 | 1314 | except: 1315 | info('Hash control result has an ERROR..!') 1316 | hashFlag = 0 1317 | break 1318 | 1319 | verifyF = 0 1320 | # If the block carries values 1321 | if block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1322 | str(blockCode11).encode(utf_type)).hexdigest(): 1323 | 1324 | info('The block carries values !!!') 1325 | try: 1326 | if str(block.prevHash).startswith('000') or \ 1327 | str(block.prevHash) == '0180BC6C2B65E51ECE943BEEF82D702AC273DF262DC2A6EE0F67CC99B4E0F546286C4'\ 1328 | 'D63CD74F5FD8128EE95FE16210A6905BB4A3F6B57CED281410D9FBA8598': 1329 | 1330 | info('Value(s) starting point is OK.') 1331 | objs = found_block_ok_objs(block.hash, IP_Add, 2) 1332 | 1333 | if objs == 2: 1334 | debug('Unknown hash!') 1335 | break 1336 | 1337 | elif objs == 1: 1338 | debug('Same IP hash!') 1339 | break 1340 | 1341 | else: 1342 | pF = 1 1343 | 1344 | for prevS in objs.prevHash: 1345 | 1346 | if prevS == block.prevHash: 1347 | pF = 0 1348 | info('Block values are already appended!') 1349 | break 1350 | 1351 | else: 1352 | pF = 1 1353 | 1354 | if pF == 1: 1355 | info('Block values are appending..!') 1356 | objs.prevHash.append(block.prevHash) 1357 | objs.blockID.append(block.blockID) 1358 | objs.counter.append(1) 1359 | 1360 | else: 1361 | 1362 | for index in range(0, len(objs.prevHash)): 1363 | 1364 | if objs.prevHash[index] == block.prevHash: 1365 | 1366 | if objs.blockID[index] == block.blockID: 1367 | 1368 | objs.counter[index] += 1 1369 | if len(hosts_of_chains) / 2 < objs.counter[index]: 1370 | info('BlockValues are setting..!') 1371 | blockID = found_blockid_hash(block.blockID) 1372 | prevHash = block.prevHash 1373 | block_previd_obj.remove(objs) 1374 | del objs 1375 | break 1376 | 1377 | except: 1378 | debug('Block values corrupted!') 1379 | 1380 | break 1381 | 1382 | # Check the queue_verify 1383 | elif qSize(queue_verify) != 0 and hashFlag == 1: 1384 | info('VerifyQ is NOT Empty!') 1385 | 1386 | # Empty queue 1387 | if qSize(temp_hash_q) != 0: 1388 | for qs in range(0, qSize(temp_hash_q)): 1389 | qGet(temp_hash_q) 1390 | 1391 | # Check the block hash and queue_verify hash(es) 1392 | for size in range(0, qSize(queue_verify)): 1393 | hashTmp = l0(qGet(queue_verify)) 1394 | 1395 | # Block was in the queue_verify 1396 | if block.hash == hashTmp.hash: 1397 | info('The block already exists in the verify Queue..!') 1398 | 1399 | # Get object and flag values if exists 1400 | calcObj, createF = found_block_ok_objs(block.hash, IP_Add, 0) 1401 | 1402 | # Already created, check IP 1403 | if createF == 1: 1404 | for IPs in calcObj.IP: 1405 | if IPs == IP_Add: 1406 | dupF = 0 1407 | debug('Duplicated block has come!') 1408 | break 1409 | else: 1410 | dupF = 1 1411 | 1412 | elif createF == 0: 1413 | dupF = 1 1414 | 1415 | # If answer is not duplicated one. 1416 | if dupF == 1: 1417 | info('Answer is NOT duplicated.') 1418 | 1419 | # If it's OK Block 1420 | if block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1421 | str(blockCode03).encode(utf_type)).hexdigest(): 1422 | info('It is (+)OK Block.') 1423 | calcObj.ok += 1 1424 | 1425 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1426 | str(blockCode02).encode(utf_type)).hexdigest(): 1427 | info('It is (-)NoK Block.') 1428 | calcObj.NoK += 1 1429 | 1430 | else: 1431 | debug('It is (~)NULL Block!') 1432 | 1433 | # Control hosts and their answers 1434 | if len(hosts_of_chains) / 2 < int(calcObj.ok): 1435 | info('Hosts OK & NoK are verified!') 1436 | 1437 | # If the block verified more than 51% 1438 | if calcObj.ok > calcObj.NoK: 1439 | 1440 | # Delete block_ok_obj object 1441 | remove_block_ok_objs(block.hash) 1442 | 1443 | # Re-Calculation of block hash with blockCode[5] 1444 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 1445 | str(blockCode05).encode(utf_type)).hexdigest() 1446 | 1447 | # Send a broadcast block ,CHAINS to add. 1448 | for hosts in hosts_of_chains: 1449 | while True: 1450 | if queue_block_whom.qsize() != 0: 1451 | block.who = queue_block_whom.get() 1452 | break 1453 | sleep(0.05) 1454 | 1455 | # Change blockID value for attacks 1456 | fakeID_1 = randint(0, 999999999999999999999999) 1457 | fakeID_2 = randint(0, 999999999999999999999999) 1458 | block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 1459 | 1460 | sign_block(block) 1461 | connect(hosts, block) 1462 | 1463 | # Send the block to the Django (USER) Side 1464 | # To say that the block added to the blockchain 1465 | # Is completed successfully 1466 | block.process = 'ok' 1467 | userConnect(block) 1468 | 1469 | verifyF = 1 1470 | 1471 | break 1472 | 1473 | # If the server has more answers then number of chains 1474 | elif len(hosts_of_chains) < calcObj.ok + calcObj.NoK: 1475 | 1476 | # Delete block_ok_obj object 1477 | remove_block_ok_objs(block.hash) 1478 | 1479 | verifyF = 1 1480 | 1481 | break 1482 | 1483 | else: 1484 | qPut(queue_verify, d0(hashTmp)) 1485 | 1486 | else: 1487 | qPut(queue_verify, d0(hashTmp)) 1488 | 1489 | # If the block is NOT in the queue_verify 1490 | if verifyF == 0 and hashFlag == 1: 1491 | 1492 | # Check the block is coming for User Side confirmation 1493 | if block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1494 | str(blockCode09).encode(utf_type)).hexdigest(): 1495 | 1496 | info('The block is in the blockchain.') 1497 | 1498 | # Notify the user for VALID block.hash is getting.. 1499 | block.process = 'ok' 1500 | userConnect(block) 1501 | 1502 | # There is NOT any block in the blockchain 1503 | elif block.totalHash == SHA512.new(str(block.hash).encode(utf_type) + 1504 | str(blockCode08).encode(utf_type)).hexdigest(): 1505 | 1506 | info('The block is NOT in the blockchain!') 1507 | 1508 | # Notify the user for INVALID block.hash is getting.. 1509 | block.process = 'nok' 1510 | userConnect(block) 1511 | 1512 | break 1513 | 1514 | miner_thread_lock.release() 1515 | 1516 | 1517 | # SERVER SIDE 1518 | # Receive data from the socket 1519 | class ClientThread(Thread): 1520 | def __init__(self, conn, IP_ADD): 1521 | Thread.__init__(self) 1522 | self.IP_ADD = IP_ADD 1523 | self.conn = conn 1524 | 1525 | def run(self): 1526 | while True: 1527 | # Get data from peers 1528 | try: 1529 | # Receive bytes 1530 | tempBytes = self.conn.recv(4096) 1531 | 1532 | global shared_pairs 1533 | global tempBlock 1534 | global ecdh_obj 1535 | global certificate 1536 | 1537 | if str(shared_pairs) == '0' and len(codes_of_block) == 0: 1538 | # If the public key received 1539 | try: 1540 | 1541 | if len(codes_of_block) == 0: 1542 | 1543 | if str(tempBytes.decode(utf_type)).startswith("-----BEGIN PUBLIC KEY-----") and \ 1544 | "-----END PUBLIC KEY-----" in str(tempBytes.decode(utf_type)): 1545 | shared_pairs = ecdh_obj.findsharedKEY(deserialize_pubkey(tempBytes)) 1546 | certificate = tempBytes 1547 | tempBlock = [] 1548 | break 1549 | 1550 | else: 1551 | break 1552 | 1553 | break 1554 | 1555 | except: 1556 | pass 1557 | 1558 | elif str(shared_pairs) != '0' and len(codes_of_block) == 0: 1559 | try: 1560 | tempBlock.append(tempBytes) 1561 | 1562 | if len(tempBlock) == 13: 1563 | 1564 | for blockcodes in tempBlock: 1565 | codes_of_block.append(aes_decryption_func(derivation_keys(shared_pairs), shared_pairs, blockcodes)) 1566 | 1567 | global blockCode00, blockCode01, blockCode02, blockCode03 1568 | global blockCode04, blockCode05, blockCode06, blockCode07 1569 | global blockCode08, blockCode09, blockCode10, blockCode11 1570 | global blockCode11, blockCode12 1571 | 1572 | blockCode12 = SHA512.new(str(codes_of_block[12]).encode(utf_type)).hexdigest() 1573 | blockCode11 = SHA512.new(str(codes_of_block[11]).encode(utf_type)).hexdigest() 1574 | blockCode10 = SHA512.new(str(codes_of_block[10]).encode(utf_type)).hexdigest() 1575 | blockCode09 = SHA512.new(str(codes_of_block[9]) .encode(utf_type)).hexdigest() 1576 | blockCode08 = SHA512.new(str(codes_of_block[8]) .encode(utf_type)).hexdigest() 1577 | blockCode07 = SHA512.new(str(codes_of_block[7]) .encode(utf_type)).hexdigest() 1578 | blockCode06 = SHA512.new(str(codes_of_block[6]) .encode(utf_type)).hexdigest() 1579 | blockCode05 = SHA512.new(str(codes_of_block[5]) .encode(utf_type)).hexdigest() 1580 | blockCode04 = SHA512.new(str(codes_of_block[4]) .encode(utf_type)).hexdigest() 1581 | blockCode03 = SHA512.new(str(codes_of_block[3]) .encode(utf_type)).hexdigest() 1582 | blockCode02 = SHA512.new(str(codes_of_block[2]) .encode(utf_type)).hexdigest() 1583 | blockCode01 = SHA512.new(str(codes_of_block[1]) .encode(utf_type)).hexdigest() 1584 | blockCode00 = SHA512.new(str(codes_of_block[0]) .encode(utf_type)).hexdigest() 1585 | 1586 | for blocks in tempBlock: 1587 | tempBlock.remove(blocks) 1588 | del blocks 1589 | 1590 | break 1591 | 1592 | except: 1593 | pass 1594 | 1595 | else: 1596 | # If others public came.. 1597 | try: 1598 | changed = 0 1599 | public = aes_decryption_func(derivation_keys(shared_pairs), shared_pairs, tempBytes).encode(utf_type) 1600 | IP = public.decode('utf-8').split('\n')[-1] 1601 | 1602 | for publics in public_storage: 1603 | if publics[1] == IP: 1604 | publics = ((deserialize_pubkey(public), IP)) 1605 | changed = 1 1606 | 1607 | if changed == 0: 1608 | public_storage.append((deserialize_pubkey(public), IP)) 1609 | 1610 | except: 1611 | pass 1612 | 1613 | # Block Reloading.. 1614 | try: 1615 | block = loadRecv(l0(tempBytes).decode("ISO-8859-1")) 1616 | block = obj(block) 1617 | 1618 | except: 1619 | 1620 | try: 1621 | block = loads(l0(tempBytes).decode("ISO-8859-1"), object_hook=decoder) 1622 | block = obj(block) 1623 | 1624 | except: 1625 | 1626 | try: 1627 | block = l0(tempBytes) 1628 | 1629 | except: 1630 | break 1631 | 1632 | # IP address validation for hosts_of_chains 1633 | for hosts in hosts_of_chains: 1634 | if hosts == self.IP_ADD: 1635 | info('IP [' + str(self.IP_ADD) + '] is in the chain list.') 1636 | connFlag = 1 1637 | break 1638 | 1639 | else: 1640 | connFlag = 0 1641 | 1642 | # The data is coming from the UNKNOWN sender 1643 | if connFlag == 0: 1644 | if self.IP_ADD != auth_server: 1645 | debug('UNKNOWN Sender !!!') 1646 | break 1647 | else: 1648 | info('IP [' + str(self.IP_ADD) + '] is authentication list.') 1649 | 1650 | # If Data does not LOAD! 1651 | except ConnectionResetError: 1652 | debug('Connection Reset by [' + self.IP_ADD + ']') 1653 | break 1654 | 1655 | except AttributeError: 1656 | debug('Data is broken !') 1657 | break 1658 | 1659 | except: 1660 | warning('Connection ERROR !') 1661 | break 1662 | 1663 | info('[' + self.IP_ADD + '] is connected.') 1664 | 1665 | try: 1666 | # Block has something: 1667 | if block != "": 1668 | info('The block is NOT an empty BLOCK.') 1669 | 1670 | info('Identifying sender..') 1671 | try: 1672 | whoFlag = 4 1673 | whoHash = block.who 1674 | # Get the iteration number 1675 | groups = [whoHash[-1]] 1676 | 1677 | # Split the headers 1678 | for splitter in range(0, 11): 1679 | if splitter % 2 == 0: 1680 | groups.append(whoHash[splitter] + whoHash[splitter + 1]) 1681 | 1682 | # Get correct hash length 1683 | whoHash = whoHash[12:-1] 1684 | 1685 | # Shifting hash 1686 | if int(groups[0]) != 0: 1687 | for times in range(0, int(groups[0])): 1688 | sftHash = '' 1689 | temp = whoHash[127] 1690 | 1691 | for item in range(0, 128): 1692 | sftHash += whoHash[item] 1693 | 1694 | sftHash = temp + sftHash 1695 | whoHash = sftHash 1696 | newHash = whoHash[:-1] 1697 | 1698 | else: 1699 | newHash = whoHash 1700 | 1701 | # Convert groups elements.. 1702 | for gRange in range(1, len(groups)): 1703 | groups[gRange] = conv_10(groups[gRange]) 1704 | 1705 | # Check hash ... 1706 | if str(newHash).startswith('0'): 1707 | 1708 | if not int(conv_mod_10(newHash[groups[-1]])) == int(conv_mod_10(newHash[groups[-2]])): 1709 | 1710 | # BLOCKCHAIN SERVER PART 1711 | # Check hash by using groups rules - PART I 1712 | if int(conv_mod_10(newHash[groups[-1]])) == int(conv_mod_10(newHash[groups[-3]])): 1713 | 1714 | # Check hash by using groups rules - PART II 1715 | if (int(conv_mod_10(newHash[groups[-2]])) + int( 1716 | conv_mod_10(newHash[groups[-4]]))) % 10 == \ 1717 | int(conv_mod_10(newHash[groups[-5]])): 1718 | 1719 | # Check hash by using groups rules - PART III 1720 | if (int(conv_mod_10(newHash[groups[-1]])) + int( 1721 | conv_mod_10(newHash[groups[-3]]))) % 10 == \ 1722 | int(conv_mod_10(newHash[groups[-5]])): 1723 | # Correct Hash 1724 | # Comes from blockchain part 1725 | whoFlag = 3 1726 | 1727 | try: 1728 | # Check digital signature in the block 1729 | verifyFlag = 0 1730 | 1731 | for publics in public_storage: 1732 | if str(self.IP_ADD) == str(publics[1]): 1733 | if ecdh_obj.verify_message(public_key=publics[0], 1734 | message=block.totalHash, 1735 | sign=block.verKey): 1736 | info('Message verifying result is TRUE.') 1737 | verifyFlag = 1 1738 | break 1739 | 1740 | # Message verified.. 1741 | if verifyFlag == 1: 1742 | 1743 | if whoFlag == 3: 1744 | info('The blockchain sends the block!') 1745 | qPut(queue_chain, (block, self.IP_ADD)) 1746 | 1747 | except: 1748 | debug('Message verifying result has an ERROR!') 1749 | 1750 | 1751 | except: 1752 | pass 1753 | 1754 | except: 1755 | pass 1756 | 1757 | break 1758 | 1759 | 1760 | def Calc(merkle, lower, upper): 1761 | # Calculate and find hash value by using hard proof-of-work 1762 | while True: 1763 | for nonce in range(lower, upper): 1764 | # If hash startswith '00000' , Done! 1765 | if str(SHA512.new(str(merkle).encode(utf_type) + str(nonce).encode(utf_type)).hexdigest()).startswith('00000'): 1766 | root = SHA512.new(str(merkle).encode(utf_type) + str(nonce).encode(utf_type)).hexdigest() 1767 | if not queue_proofofwork.qsize() != 0: 1768 | try: 1769 | queue_proofofwork.put(root, timeout=1) 1770 | queue_proofofwork.put(nonce, timeout=1) 1771 | except: 1772 | debug('calc_pow_hash Queue has an ERROR..!') 1773 | break 1774 | break 1775 | 1776 | 1777 | # Calculate hash value calc_pow_hash 1778 | def calc_pow_hash(Block): 1779 | info('calc_pow_hash starting...') 1780 | global prevHash 1781 | global blockID 1782 | 1783 | while True: 1784 | if queue_proofofwork.qsize() != 0: 1785 | queue_proofofwork.get() 1786 | else: 1787 | break 1788 | 1789 | # Hash proof of work.. 1790 | Block.blockID = int(blockID) 1791 | Block.prevHash = prevHash 1792 | blockID = '0' 1793 | 1794 | newsenderID = SHA512.new(str(Block.senderID).encode(utf_type)).hexdigest() 1795 | newreceiverID = SHA512.new(str(Block.receiverID).encode(utf_type)).hexdigest() 1796 | newMessage = SHA512.new(str(Block.message).encode(utf_type)).hexdigest() 1797 | newTimestamp = SHA512.new(str(Block.timestamp).encode(utf_type)).hexdigest() 1798 | newDS = SHA512.new(str(Block.digitalSignature).encode(utf_type)).hexdigest() 1799 | newPrevHash = SHA512.new(str(Block.prevHash).encode(utf_type)).hexdigest() 1800 | newblockID = SHA512.new(str(Block.blockID).encode(utf_type)).hexdigest() 1801 | 1802 | merkle = '' 1803 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newsenderID).encode(utf_type)).hexdigest() 1804 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newreceiverID).encode(utf_type)).hexdigest() 1805 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newMessage).encode(utf_type)).hexdigest() 1806 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newTimestamp).encode(utf_type)).hexdigest() 1807 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newDS).encode(utf_type)).hexdigest() 1808 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newPrevHash).encode(utf_type)).hexdigest() 1809 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newblockID).encode(utf_type)).hexdigest() 1810 | 1811 | # Set lower and upper bounds 1812 | lower = 0 1813 | upper = 500000 1814 | 1815 | # Create a List to hold all processes 1816 | procs = [] 1817 | 1818 | while True: 1819 | # If the queue_proofofwork is OK, break 1820 | if queue_proofofwork.qsize() == 2: 1821 | root = queue_proofofwork.get() 1822 | nonce = queue_proofofwork.get() 1823 | break 1824 | 1825 | # Check if one of the process is NOT alive, 1826 | # Add new one. 1827 | elif len(procs) % 10 == 0 and len(procs) != 0: 1828 | for prN in range(0, len(procs)): 1829 | if not procs[prN].is_alive(): 1830 | procs.remove(procs[prN]) 1831 | procs.append(Process(target=Calc, args=(merkle, lower, upper))) 1832 | lower += 500000 1833 | upper += 500000 1834 | procs[-1].start() 1835 | break 1836 | else: 1837 | # Create 5 processes 1838 | if len(procs) % 10 != 0 or len(procs) == 0: 1839 | procs.append(Process(target=Calc, args=(merkle, lower, upper))) 1840 | lower += 500000 1841 | upper += 500000 1842 | procs[-1].start() 1843 | 1844 | # Terminate and remove them 1845 | for proc in procs: 1846 | proc.join() 1847 | proc.terminate() 1848 | procs.remove(proc) 1849 | 1850 | while True: 1851 | if queue_proofofwork.qsize() != 0: 1852 | queue_proofofwork.get() 1853 | else: 1854 | break 1855 | 1856 | return root, nonce 1857 | 1858 | 1859 | # Verify user block(s) 1860 | def verifying_user_blocks(Block, Flag): 1861 | 1862 | # Soft control.. 1863 | if Flag == 0: 1864 | info('Soft control..') 1865 | newsenderID = SHA512.new(str(Block.senderID).encode(utf_type)).hexdigest() 1866 | newreceiverID = SHA512.new(str(Block.receiverID).encode(utf_type)).hexdigest() 1867 | newMessage = SHA512.new(str(Block.message).encode(utf_type)).hexdigest() 1868 | newTimestamp = SHA512.new(str(Block.timestamp).encode(utf_type)).hexdigest() 1869 | 1870 | # Create a merkle tree 1871 | merkle = '' 1872 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newsenderID).encode(utf_type)).hexdigest() 1873 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newreceiverID).encode(utf_type)).hexdigest() 1874 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newMessage).encode(utf_type)).hexdigest() 1875 | root = SHA512.new(str(merkle).encode(utf_type) + str(newTimestamp).encode(utf_type)).hexdigest() 1876 | 1877 | if Block.hash == root: 1878 | info('User hash control is OK') 1879 | return True 1880 | else: 1881 | debug('User hash control is NOT ok!') 1882 | return False 1883 | 1884 | # Hard control.. 1885 | elif Flag == 1: 1886 | info('Hard control..') 1887 | global blockid_end 1888 | get_blockid_hash() 1889 | 1890 | timer = 0 1891 | while True: 1892 | sleep(6) 1893 | if blockID == '0': 1894 | timer += 1 1895 | sleep(2) 1896 | 1897 | else: 1898 | break 1899 | 1900 | if timer % 2 == 0: 1901 | get_blockid_hash() 1902 | 1903 | debug('User message is waiting...') 1904 | 1905 | # Fill the block values 1906 | blockid_end = blockID 1907 | Block.blockID = blockID 1908 | root = main_block(Block) 1909 | 1910 | if Block.totalHash == SHA512.new(str(root).encode(utf_type) + 1911 | str(blockCode10).encode(utf_type)).hexdigest(): 1912 | 1913 | info('User hash control is OK [conf.]') 1914 | return True 1915 | 1916 | else: 1917 | debug('User hash control is NOT ok! [conf]') 1918 | return False 1919 | 1920 | else: 1921 | warning('Hash control has an ERROR!') 1922 | return False 1923 | 1924 | 1925 | # User operations.. 1926 | def user_operations(): 1927 | while True: 1928 | 1929 | while True: 1930 | if int(queue_user.qsize()) != 0: 1931 | infos = qGet(queue_user) 1932 | block = infos[0] 1933 | IP_Add = infos[1] 1934 | break 1935 | 1936 | user_thread_lock.acquire() 1937 | while True: 1938 | global blockID 1939 | 1940 | try: 1941 | # Check the block type.. 1942 | if str(block.totalHash) == '0' and str(block.blockID) == '0' and \ 1943 | str(block.prevHash) == '0' and str(block.who) == '0': 1944 | 1945 | info('The block comes from the user for calc_pow_hash operations!') 1946 | 1947 | if verifying_user_blocks(block, 0): 1948 | info('User [soft] hash control result is TRUE.') 1949 | userhashF = 1 1950 | 1951 | else: 1952 | info('User [soft] hash control result is FALSE!') 1953 | userhashF = 0 1954 | break 1955 | 1956 | else: 1957 | 1958 | info('The block comes for confirmation operations.') 1959 | 1960 | if verifying_user_blocks(block, 1): 1961 | info('User [hard] hash control result is TRUE.') 1962 | userhashF = 1 1963 | 1964 | else: 1965 | info('User [hard] hash control result is FALSE!') 1966 | userhashF = 0 1967 | break 1968 | 1969 | except: 1970 | try: 1971 | # If the blockhash come..! 1972 | if len(block) == 128: 1973 | 1974 | if block.startswith(b'00000'): 1975 | userhashF = 2 1976 | 1977 | else: 1978 | debug('Blockhash bytes has an ERROR..!') 1979 | break 1980 | 1981 | else: 1982 | debug('Blockhash size has an ERROR..!') 1983 | break 1984 | 1985 | except: 1986 | debug('Block attributes has an ERROR..!') 1987 | break 1988 | 1989 | # If hash is correct 1990 | if userhashF == 1: 1991 | 1992 | # Control totalHash value 1993 | if str(block.totalHash) == "0": 1994 | 1995 | global blockid_end 1996 | get_blockid_hash() 1997 | 1998 | timer = 0 1999 | while True: 2000 | sleep(6) 2001 | if blockID == '0': 2002 | timer += 1 2003 | sleep(2) 2004 | 2005 | else: 2006 | break 2007 | 2008 | if timer % 2 == 0: 2009 | get_blockid_hash() 2010 | 2011 | debug('User message is waiting...') 2012 | 2013 | # Fill the block values 2014 | global prevHash 2015 | blockid_end = blockID 2016 | 2017 | while True: 2018 | if queue_block_whom.qsize() != 0: 2019 | block.who = queue_block_whom.get() 2020 | break 2021 | sleep(0.05) 2022 | 2023 | block.prevHash = prevHash 2024 | block.hash, block.nonce = calc_pow_hash(block) 2025 | 2026 | fakeID_1 = randint(0, 999999999999999999999999) 2027 | fakeID_2 = randint(0, 999999999999999999999999) 2028 | block.blockID = SHA512.new(str(fakeID_1 + fakeID_2).encode(utf_type)).hexdigest() 2029 | 2030 | # Get random block code and send it 2031 | randCode = SHA512.new(str(codes_of_block[randint(0, 10)]).encode(utf_type)).hexdigest() 2032 | 2033 | block.totalHash = SHA512.new(str(block.hash).encode(utf_type) + 2034 | str(randCode).encode(utf_type)).hexdigest() 2035 | 2036 | qPut(queue_verify, d0(block)) 2037 | 2038 | # Broadcast the block to all chains 2039 | for host in hosts_of_chains: 2040 | sign_block(block) 2041 | connect(host, block) 2042 | 2043 | # Confirmation blockhash 2044 | elif userhashF == 2: 2045 | while True: 2046 | if queue_fakeblock.qsize() != 0: 2047 | reqBlock = queue_fakeblock.get() 2048 | break 2049 | sleep(0.05) 2050 | 2051 | reqBlock.prevHash = str(block) 2052 | reqBlock.totalHash = SHA512.new(str(reqBlock.hash).encode(utf_type) + 2053 | str(blockCode10).encode(utf_type)).hexdigest() 2054 | 2055 | # userWho set 2056 | while True: 2057 | if queue_user_whom.qsize() != 0: 2058 | reqBlock.who = queue_user_whom.get() 2059 | break 2060 | sleep(0.05) 2061 | 2062 | for host in hosts_of_chains: 2063 | if host == hosts_of_chains[-1]: 2064 | sign_block(reqBlock) 2065 | if connect(host, reqBlock): 2066 | break 2067 | 2068 | else: 2069 | for hosts in hosts_of_chains: 2070 | sign_block(reqBlock) 2071 | if connect(hosts, reqBlock): 2072 | break 2073 | 2074 | # To select random chainHost each request 2075 | if randint(0, 1): 2076 | sign_block(reqBlock) 2077 | if connect(host, reqBlock): 2078 | break 2079 | 2080 | break 2081 | 2082 | user_thread_lock.release() 2083 | 2084 | 2085 | # USER SERVER CONNECTION 2086 | # Receive data from the socket 2087 | class ClientUserThread(Thread): 2088 | def __init__(self, conn, IP_ADD): 2089 | Thread.__init__(self) 2090 | self.IP_ADD = IP_ADD 2091 | self.conn = conn 2092 | 2093 | def run(self): 2094 | while True: 2095 | 2096 | # Get data from the peer 2097 | try: 2098 | 2099 | # Receive bytes 2100 | tempBytes = self.conn.recv(4096) 2101 | 2102 | info('The block is reloading...') 2103 | 2104 | # Block Reloading.. 2105 | try: 2106 | block = loadRecv(tempBytes.decode("ISO-8859-1")) 2107 | block = obj(block) 2108 | 2109 | except: 2110 | 2111 | try: 2112 | block = loads(tempBytes.decode("ISO-8859-1"), object_hook=decoder) 2113 | block = obj(block) 2114 | 2115 | except: 2116 | 2117 | try: 2118 | if len(tempBytes) == 128: 2119 | block = tempBytes 2120 | 2121 | elif tempBytes == b'estimatedtime': 2122 | userConnect('estimatedtime' + str(queue_get_time())) 2123 | break 2124 | 2125 | else: 2126 | debug('The block can NOT reload!') 2127 | break 2128 | 2129 | except: 2130 | block = "" 2131 | debug('The block can NOT reload!') 2132 | break 2133 | 2134 | # If Data does not LOAD! 2135 | except ConnectionResetError: 2136 | debug('Connection Reset by [' + self.IP_ADD + ']') 2137 | break 2138 | 2139 | except AttributeError: 2140 | debug('Data is broken !') 2141 | break 2142 | 2143 | except: 2144 | warning('Connection ERROR !') 2145 | break 2146 | 2147 | # Block has something: 2148 | if block != "": 2149 | qPut(queue_user, (block, self.IP_ADD)) 2150 | 2151 | break 2152 | 2153 | 2154 | def block_who_miner_func(): 2155 | while True: 2156 | if queue_block_whom.qsize() >= 499: 2157 | sleep(15) 2158 | 2159 | else: 2160 | who = generate_mining_hash() 2161 | try: 2162 | queue_block_whom.put(who) 2163 | except: 2164 | queue_block_whom.get() 2165 | try: 2166 | queue_block_whom.put(who) 2167 | except: 2168 | pass 2169 | 2170 | 2171 | def block_who_user_func(): 2172 | while True: 2173 | if queue_user_whom.qsize() >= 499: 2174 | sleep(15) 2175 | 2176 | else: 2177 | who = generate_user_hash() 2178 | try: 2179 | queue_user_whom.put(who) 2180 | except: 2181 | queue_user_whom.get() 2182 | try: 2183 | queue_user_whom.put(who) 2184 | except: 2185 | pass 2186 | 2187 | 2188 | # Listen all connections from Blockchain Server 2189 | def listen_all_chain_conns(): 2190 | info('"Blockchain Server" side is preparing..') 2191 | tcpServer = socket(AF_INET, SOCK_STREAM) 2192 | tcpServer.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 2193 | tcpServer.bind((current_address, chain_port)) 2194 | tcpServer.listen(200) 2195 | 2196 | context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH) 2197 | context.load_cert_chain('selfsigned.cert', 'selfsigned.key') 2198 | context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 2199 | context.set_ciphers('EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH') 2200 | 2201 | threadsX = [] 2202 | info('"Blockchain Server" side is ready to listen.') 2203 | 2204 | while True: 2205 | 2206 | try: 2207 | (conn, (IP_ADD, port_number_ADD)) = tcpServer.accept() 2208 | info('[' + str(IP_ADD) + ']:[' + str(port_number_ADD) + '] is connecting...') 2209 | conn = context.wrap_socket(conn, server_side=True) 2210 | newthread = ClientThread(conn, IP_ADD) 2211 | newthread.start() 2212 | threadsX.append(newthread) 2213 | 2214 | except ssl.SSLError: 2215 | debug('Sender does NOT use SSL..!') 2216 | 2217 | except: 2218 | pass 2219 | 2220 | try: 2221 | if not threadsX[0].is_alive(): 2222 | del threadsX[0] 2223 | except: 2224 | pass 2225 | 2226 | for th in threadsX: 2227 | th.join() 2228 | 2229 | 2230 | # Listen all connections from User Server 2231 | def listen_all_conns(): 2232 | info('"User Server" side is preparing..') 2233 | tcpServer2 = socket(AF_INET, SOCK_STREAM) 2234 | tcpServer2.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 2235 | tcpServer2.bind((binding_address, user_port)) 2236 | tcpServer2.listen(200) 2237 | threads = [] 2238 | info('"User Server" side is ready to listen.') 2239 | 2240 | while True: 2241 | try: 2242 | (conn, (IP_ADD, port_number_ADD)) = tcpServer2.accept() 2243 | info('[' + str(IP_ADD) + ']:[' + str(port_number_ADD) + '] is connecting...') 2244 | newthread = ClientUserThread(conn, IP_ADD) 2245 | newthread.start() 2246 | threads.append(newthread) 2247 | except: 2248 | pass 2249 | 2250 | try: 2251 | if not threads[0].is_alive(): 2252 | del threads[0] 2253 | except: 2254 | pass 2255 | 2256 | for t in threads: 2257 | t.join() 2258 | 2259 | 2260 | # Main func for the mining part 2261 | def main(): 2262 | # Generate fakeblocks 2263 | gengenerating_fake_block = Thread(target=gen_fake_block, ) 2264 | gengenerating_fake_block.start() 2265 | sleep(0.5) 2266 | 2267 | # Create a listening server for User Server 2268 | listenUser = Thread(target=listen_all_conns, ) 2269 | listenUser.start() 2270 | sleep(0.5) 2271 | 2272 | # Mining Operations... 2273 | minerOps = Thread(target=mining_operations, ) 2274 | minerOps.start() 2275 | sleep(0.5) 2276 | 2277 | # User Operations... 2278 | userOps = Thread(target=user_operations, ) 2279 | userOps.start() 2280 | sleep(0.5) 2281 | 2282 | 2283 | if __name__ == '__main__': 2284 | try: 2285 | engine_func() 2286 | 2287 | except KeyboardInterrupt: 2288 | debug('Keyboard Interrupt is occured!') 2289 | quitLog() 2290 | exit() 2291 | 2292 | except AttributeError: 2293 | debug('Attribute Error: ' + str(AttributeError.__doc__)) 2294 | quitLog() 2295 | exit() 2296 | 2297 | except: 2298 | debug('Something was wrong..!') 2299 | quitLog() 2300 | exit() 2301 | -------------------------------------------------------------------------------- /users_part.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | ################################################ 4 | # EMRE OVUNC # 5 | ################################################ 6 | # info@emreovunc.com # 7 | ################################################ 8 | # USERS PART # 9 | ################################################ 10 | 11 | from sys import exit 12 | from time import sleep 13 | from json import JSONEncoder 14 | from json import dumps 15 | from json import loads 16 | from queue import Queue 17 | from random import randint 18 | from socket import socket 19 | from socket import AF_INET 20 | from socket import SOCK_STREAM 21 | from socket import SOL_SOCKET 22 | from socket import SO_REUSEADDR 23 | from datetime import datetime as dt 24 | from threading import Thread 25 | from threading import Lock 26 | from Crypto.Hash import SHA512 27 | from cryptography.hazmat.backends import default_backend 28 | from cryptography.hazmat.primitives import hashes 29 | from cryptography.hazmat.primitives import serialization 30 | from cryptography.hazmat.primitives.ciphers import Cipher 31 | from cryptography.hazmat.primitives.ciphers import algorithms 32 | from cryptography.hazmat.primitives.ciphers import modes 33 | from cryptography.hazmat.primitives.kdf.hkdf import HKDF 34 | from cryptography.hazmat.primitives.asymmetric import ec 35 | 36 | 37 | utf_type = 'utf-8' 38 | user_ip = '127.0.0.1' 39 | port = 31313 40 | user_msg = 44444 41 | 42 | queue_user = Queue(maxsize = 500) 43 | 44 | validBlock = [] 45 | invalidBlock = [] 46 | lock_user = Lock() 47 | 48 | 49 | # Generate a fake block 50 | class user_block: 51 | def __init__(self , id_block , id_sender , id_receiver, 52 | message , timestamp , hash , _id , 53 | prevHash , who , digital_signature , verKey , 54 | totalHash, nonce): 55 | 56 | # Fill values with random hash(s) 57 | self.id_block = id_block 58 | self.id_sender = id_sender 59 | self.id_receiver = id_receiver 60 | self.message = message 61 | self.timestamp = timestamp 62 | self.hash = hash 63 | self._id = _id 64 | self.prevHash = prevHash 65 | self.nonce = nonce 66 | self.who = who 67 | signMSG = (str(self.id_sender) + str(self.id_receiver) + 68 | str(self.message) + str(self.timestamp)).encode(utf_type) 69 | self.digital_signature = 0 70 | self.verKey = 0 71 | 72 | newid_sender = SHA512.new(str(self.id_sender).encode(utf_type)).hexdigest() 73 | newid_receiver = SHA512.new(str(self.id_receiver).encode(utf_type)).hexdigest() 74 | newMessage = SHA512.new(str(self.message).encode(utf_type)).hexdigest() 75 | newTimestamp = SHA512.new(str(self.timestamp).encode(utf_type)).hexdigest() 76 | 77 | merkle = '' 78 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newid_sender).encode(utf_type)).hexdigest() 79 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newid_receiver).encode(utf_type)).hexdigest() 80 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newMessage).encode(utf_type)).hexdigest() 81 | merkle = SHA512.new(str(merkle).encode(utf_type) + str(newTimestamp).encode(utf_type)).hexdigest() 82 | self.hash = merkle 83 | self.totalHash = totalHash 84 | 85 | 86 | # Get current time 87 | def get_current_time(): 88 | now = dt.now() 89 | time = now.isoformat() 90 | return time 91 | 92 | 93 | # Signing the message 94 | def sign_message(private_key, message): 95 | message = message.encode(utf_type) 96 | sign = private_key.sign(message, ec.ECDSA(hashes.SHA256())) 97 | return sign 98 | 99 | 100 | # Verifying the message 101 | def verify_message(public_key, message, sign): 102 | message = message.encode(utf_type) 103 | return public_key.verify(sign, message, ec.ECDSA(hashes.SHA256())) 104 | 105 | 106 | # Convert dict to object 107 | class obj(object): 108 | def __init__(self, d): 109 | 110 | for a, b in d.items(): 111 | 112 | if isinstance(b, (list, tuple)): 113 | setattr(self, a, [obj(x) if isinstance(x, dict) else x for x in b]) 114 | 115 | else: 116 | setattr(self, a, obj(b) if isinstance(b, dict) else b) 117 | 118 | 119 | # Encoder class for mongodb blocks 120 | class Encoder(JSONEncoder): 121 | def default(self, obj): 122 | if isinstance(obj, ObjectId): 123 | return str(obj) 124 | else: 125 | return obj 126 | 127 | 128 | # Decoder func. for receiving mongodb blocks 129 | def decoder(dct): 130 | for k, v in dct.items(): 131 | if '_id' in dct: 132 | try: 133 | dct['_id'] = ObjectId(dct['_id']) 134 | except: 135 | pass 136 | return dct 137 | 138 | 139 | def loadRecv(object): 140 | return loads(object) 141 | 142 | 143 | # USER SERVER CONNECTION 144 | # Receive data from the socket 145 | class ClientUserThread(Thread): 146 | def __init__(self, conn, IP_ADD): 147 | Thread.__init__(self) 148 | self.IP_ADD = IP_ADD 149 | self.conn = conn 150 | 151 | def run(self): 152 | while True: 153 | # Get data from the peer 154 | try: 155 | 156 | # Receive bytes 157 | tempBytes = self.conn.recv(4096) 158 | 159 | 160 | # Block Reloading.. 161 | try: 162 | block = loadRecv(tempBytes.decode("ISO-8859-1")) 163 | block = obj(block) 164 | 165 | except: 166 | 167 | try: 168 | block = loads(tempBytes.decode("ISO-8859-1"), object_hook=decoder) 169 | block = obj(block) 170 | 171 | except: 172 | 173 | try: 174 | if b'estimatedtime' in tempBytes: 175 | estimatedTime = str(tempBytes[13:]).split('b')[1].split("'")[1] 176 | break 177 | else: 178 | break 179 | 180 | except: 181 | break 182 | 183 | # If Data does NOT load..! 184 | except ConnectionResetError: 185 | break 186 | 187 | except AttributeError: 188 | break 189 | 190 | except: 191 | break 192 | 193 | # Block has something: 194 | if block != "": 195 | queue_user.put(block) 196 | 197 | break 198 | 199 | 200 | def connect(HOST, message): 201 | # Byte shifting values.. 202 | try: 203 | mySocket = socket(AF_INET, SOCK_STREAM) 204 | mySocket.connect((HOST, port)) 205 | 206 | # Sending bytes data.. 207 | if type(message) == bytes: 208 | 209 | mySocket.send(message) 210 | 211 | # '.obj' in str(type(message)) 212 | else: 213 | 214 | try: 215 | if "'__main__.user_block'" in str(type(message)): 216 | try: 217 | msg = dumps(message.__dict__) 218 | except: 219 | msg = dumps(message.__dict__, cls=Encoder) 220 | 221 | else: 222 | if len(message) == 128: 223 | msg = message 224 | 225 | mySocket.send(msg.encode("ISO-8859-1")) 226 | 227 | except: 228 | pass 229 | 230 | mySocket.close() 231 | return True 232 | 233 | except ConnectionRefusedError: 234 | return False 235 | 236 | except: 237 | return False 238 | 239 | 240 | # User block operations.. 241 | def user_operations(): 242 | while True: 243 | if int(queue_user.qsize()) != 0: 244 | block = queue_user.get() 245 | break 246 | 247 | lock_user.acquire() 248 | while True: 249 | 250 | try: 251 | if hasattr(block, 'process'): 252 | if block.process == 'ok': 253 | prOK = 1 254 | elif block.process == 'nok': 255 | prOK = 0 256 | else: 257 | break 258 | 259 | else: 260 | break 261 | 262 | except: 263 | break 264 | 265 | # If the block is added to the blockchain. 266 | if prOK == 1: 267 | 268 | if len(validBlock) > 10000: 269 | validBlock.remove(validBlock[0]) 270 | 271 | validBlock.append(block.prevHash) 272 | 273 | # If the block is NOT added to the blockchain. 274 | elif prOK == 0: 275 | 276 | if len(invalidBlock) > 10000: 277 | invalidBlock.remove(invalidBlock[0]) 278 | 279 | invalidBlock.append(block.prevHash) 280 | 281 | # If the process flag is NOT valid. 282 | else: 283 | break 284 | 285 | break 286 | 287 | 288 | # Get estimated message time 289 | def queue_get_time(): 290 | connect(user_ip, b'estimatedtime') 291 | 292 | 293 | # Check the block.hash is VALID or INVALID 294 | def checking(blockhash): 295 | 296 | if not str(blockhash).startswith('00000'): 297 | return 0 298 | 299 | # First things first, check the valid one 300 | try: 301 | found = 0 302 | for blocks in validBlock: 303 | if blocks == str("b'")+blockhash+str("'"): 304 | validBlock.remove(blocks) 305 | del blocks 306 | found = 1 307 | break 308 | except: 309 | found = 0 310 | 311 | # If the blockhash is NOT in the validBlocks 312 | if found == 0: 313 | 314 | # Check the invalid block 315 | try: 316 | foundi = 0 317 | for blocks in invalidBlock: 318 | if blocks == str("b'")+blockhash+str("'"): 319 | invalidBlock.remove(blocks) 320 | del blocks 321 | foundi = 1 322 | break 323 | except: 324 | foundi = 0 325 | 326 | # If the block also is NOT in the invalidBlocks 327 | if foundi == 0: 328 | connect(user_ip, blockhash) 329 | return 2 330 | 331 | # If the block found in the invalidBlocks 332 | else: 333 | return 0 334 | 335 | # If the blockhash found in the validBlocks 336 | else: 337 | return 1 338 | 339 | 340 | # Listen all connections from User Server 341 | def listen_all_conns(): 342 | tcpServer3 = socket(AF_INET, SOCK_STREAM) 343 | tcpServer3.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 344 | tcpServer3.bind((user_ip, user_msg)) 345 | tcpServer3.listen(200) 346 | threads = [] 347 | 348 | while True: 349 | try: 350 | (conn, (IP_ADD, port_ADD)) = tcpServer3.accept() 351 | newthread = ClientUserThread(conn, IP_ADD) 352 | newthread.start() 353 | threads.append(newthread) 354 | except: 355 | pass 356 | 357 | try: 358 | if not threads[0].is_alive(): 359 | del threads[0] 360 | except: 361 | pass 362 | 363 | for t in threads: 364 | t.join() 365 | 366 | # Elliptic curve key-pairs 367 | def generateECDH(): 368 | # Generate a private key for use in the exchange. 369 | private_key = ec.generate_private_key(ec.SECT571K1(), default_backend()) 370 | public_key = private_key.public_key() 371 | return private_key, public_key 372 | 373 | 374 | # To find shared secret using user's private and other's public 375 | def findsharedKEY(private_key, peer_public): 376 | shared_key = private_key.exchange(ec.ECDH(), peer_public) 377 | return shared_key 378 | 379 | 380 | # HMAC-based Extract and Expand Key Derivation Function 381 | def derivation_keys(shared_key): 382 | hkdf = HKDF( 383 | algorithm = hashes.SHA256() , 384 | length = 32 , 385 | salt = shared_key[16:32], 386 | info = shared_key[:16] , 387 | backend = default_backend()) 388 | 389 | keyDerived = hkdf.derive(shared_key[16:]) 390 | return keyDerived 391 | 392 | 393 | # AES Encryption Part 394 | def aes_encryption_func(keyDerived, shared_key, message): 395 | if not type(message) == bytes: 396 | message = message.encode(utf_type) 397 | if not type(shared_key) == bytes: 398 | shared_key = shared_key.encode(utf_type) 399 | if not type(keyDerived) == bytes: 400 | keyDerived = keyDerived.encode(utf_type) 401 | length = 16 - (len(message) % 16) 402 | message += bytes([length]) * length 403 | backend = default_backend() 404 | key = keyDerived 405 | iv = shared_key[:16] 406 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 407 | encryptor = cipher.encryptor() 408 | encrypted = encryptor.update(message) + encryptor.finalize() 409 | return encrypted 410 | 411 | 412 | # AES Decryption Part 413 | def aes_decryption_func(keyDerived, shared_key, message): 414 | if not type(message) == bytes: 415 | message = message.encode(utf_type) 416 | if not type(shared_key) == bytes: 417 | shared_key = shared_key.encode(utf_type) 418 | if not type(keyDerived) == bytes: 419 | keyDerived = keyDerived.encode(utf_type) 420 | backend = default_backend() 421 | key = keyDerived 422 | iv = shared_key[:16] 423 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 424 | decryptor = cipher.decryptor() 425 | dt = decryptor.update(message) + decryptor.finalize() 426 | decrypted = dt[:-dt[-1]].decode(utf_type) 427 | return decrypted 428 | 429 | 430 | # Serialization of Public Key 431 | def serialize_pubkey(public_key): 432 | serialized_public = public_key.public_bytes( 433 | encoding = serialization.Encoding.PEM, 434 | format = serialization.PublicFormat.SubjectPublicKeyInfo) 435 | return serialized_public 436 | 437 | 438 | # De-serialization of Public Key 439 | def deserialize_pubkey(serialized_public): 440 | loaded_public_key = serialization.load_pem_public_key( 441 | serialized_public, 442 | backend = default_backend()) 443 | return loaded_public_key 444 | 445 | 446 | # Send the block 447 | def sending_the_block(id_sender, id_receiver, message, digitalSign, verKey): 448 | 449 | eoBlock = user_block( 450 | # id_block 451 | 0, 452 | 453 | # id_sender 454 | id_sender, 455 | 456 | # id_receiver 457 | id_receiver, 458 | 459 | # message 460 | message, 461 | 462 | # timestamp 463 | get_current_time(), 464 | 465 | # hash 466 | SHA512.new(str(randint(0, 1000000) + randint(0, 99999999)).encode(utf_type)).hexdigest(), 467 | 468 | # _id 469 | SHA512.new(str(randint(0, 1000000) + randint(0, 99999999)).encode(utf_type)).hexdigest(), 470 | 471 | # prevHash 472 | 0, 473 | 474 | # who 475 | 0, 476 | 477 | # digital_signature 478 | digitalSign, 479 | 480 | # verifyKey 481 | verKey, 482 | 483 | # totalHash 484 | 0, 485 | 486 | # nonce 487 | 100) 488 | 489 | connect(user_ip, eoBlock) 490 | 491 | 492 | # Main func for the user part 493 | def main(): 494 | 495 | # Create a listening server for User Server 496 | listenUser = Thread(target=listen_all_conns, ) 497 | listenUser.start() 498 | sleep(0.5) 499 | 500 | # User Operations... 501 | userOps = Thread(target=user_operations, ) 502 | userOps.start() 503 | sleep(0.5) 504 | 505 | 506 | # Return if the hashCheck value is in the blockchain or NOT! 507 | def hash_checking_chain(hashCheck): 508 | while True: 509 | result = checking(hashCheck) 510 | 511 | # If the hash was in the blockchain 512 | if result == 1: 513 | break 514 | 515 | # Waiting answer... 516 | elif result == 2: 517 | sleep(2) 518 | 519 | # If the hash is NOT in the blockchain 520 | else: 521 | break 522 | 523 | if result == 1: 524 | return True 525 | 526 | else: 527 | return False 528 | 529 | 530 | if __name__ == '__main__': 531 | try: 532 | main() 533 | sending_the_block(0, 0, 0, 0, 0) 534 | 535 | except KeyboardInterrupt: 536 | exit() 537 | 538 | except AttributeError: 539 | exit() 540 | 541 | except: 542 | exit() 543 | --------------------------------------------------------------------------------