├── README.md └── crypto.py /README.md: -------------------------------------------------------------------------------- 1 | # Create-Cryptocurrency-in-Python 2 | This is the code for creating a simple cryptocurrency using the Python programming language 3 | -------------------------------------------------------------------------------- /crypto.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import time 3 | 4 | 5 | class Block: 6 | 7 | def __init__(self, index, proof_no, prev_hash, data, timestamp=None): 8 | self.index = index 9 | self.proof_no = proof_no 10 | self.prev_hash = prev_hash 11 | self.data = data 12 | self.timestamp = timestamp or time.time() 13 | 14 | @property 15 | def calculate_hash(self): 16 | block_of_string = "{}{}{}{}{}".format(self.index, self.proof_no, 17 | self.prev_hash, self.data, 18 | self.timestamp) 19 | 20 | return hashlib.sha256(block_of_string.encode()).hexdigest() 21 | 22 | def __repr__(self): 23 | return "{} - {} - {} - {} - {}".format(self.index, self.proof_no, 24 | self.prev_hash, self.data, 25 | self.timestamp) 26 | 27 | 28 | class BlockChain: 29 | 30 | def __init__(self): 31 | self.chain = [] 32 | self.current_data = [] 33 | self.nodes = set() 34 | self.construct_genesis() 35 | 36 | def construct_genesis(self): 37 | self.construct_block(proof_no=0, prev_hash=0) 38 | 39 | def construct_block(self, proof_no, prev_hash): 40 | block = Block( 41 | index=len(self.chain), 42 | proof_no=proof_no, 43 | prev_hash=prev_hash, 44 | data=self.current_data) 45 | self.current_data = [] 46 | 47 | self.chain.append(block) 48 | return block 49 | 50 | @staticmethod 51 | def check_validity(block, prev_block): 52 | if prev_block.index + 1 != block.index: 53 | return False 54 | 55 | elif prev_block.calculate_hash != block.prev_hash: 56 | return False 57 | 58 | elif not BlockChain.verifying_proof(block.proof_no, 59 | prev_block.proof_no): 60 | return False 61 | 62 | elif block.timestamp <= prev_block.timestamp: 63 | return False 64 | 65 | return True 66 | 67 | def new_data(self, sender, recipient, quantity): 68 | self.current_data.append({ 69 | 'sender': sender, 70 | 'recipient': recipient, 71 | 'quantity': quantity 72 | }) 73 | return True 74 | 75 | @staticmethod 76 | def proof_of_work(last_proof): 77 | '''this simple algorithm identifies a number f' such that hash(ff') contain 4 leading zeroes 78 | f is the previous f' 79 | f' is the new proof 80 | ''' 81 | proof_no = 0 82 | while BlockChain.verifying_proof(proof_no, last_proof) is False: 83 | proof_no += 1 84 | 85 | return proof_no 86 | 87 | @staticmethod 88 | def verifying_proof(last_proof, proof): 89 | #verifying the proof: does hash(last_proof, proof) contain 4 leading zeroes? 90 | 91 | guess = f'{last_proof}{proof}'.encode() 92 | guess_hash = hashlib.sha256(guess).hexdigest() 93 | return guess_hash[:4] == "0000" 94 | 95 | @property 96 | def latest_block(self): 97 | return self.chain[-1] 98 | 99 | def block_mining(self, details_miner): 100 | 101 | self.new_data( 102 | sender="0", #it implies that this node has created a new block 103 | recipient=details_miner, 104 | quantity= 105 | 1, #creating a new block (or identifying the proof number) is awarded with 1 106 | ) 107 | 108 | last_block = self.latest_block 109 | 110 | last_proof_no = last_block.proof_no 111 | proof_no = self.proof_of_work(last_proof_no) 112 | 113 | last_hash = last_block.calculate_hash 114 | block = self.construct_block(proof_no, last_hash) 115 | 116 | return vars(block) 117 | 118 | def create_node(self, address): 119 | self.nodes.add(address) 120 | return True 121 | 122 | @staticmethod 123 | def obtain_block_object(block_data): 124 | #obtains block object from the block data 125 | 126 | return Block( 127 | block_data['index'], 128 | block_data['proof_no'], 129 | block_data['prev_hash'], 130 | block_data['data'], 131 | timestamp=block_data['timestamp']) 132 | 133 | 134 | blockchain = BlockChain() 135 | 136 | print("***Mining fccCoin about to start***") 137 | print(blockchain.chain) 138 | 139 | last_block = blockchain.latest_block 140 | last_proof_no = last_block.proof_no 141 | proof_no = blockchain.proof_of_work(last_proof_no) 142 | 143 | blockchain.new_data( 144 | sender="0", #it implies that this node has created a new block 145 | recipient="Quincy Larson", #let's send Quincy some coins! 146 | quantity= 147 | 1, #creating a new block (or identifying the proof number) is awarded with 1 148 | ) 149 | 150 | last_hash = last_block.calculate_hash 151 | block = blockchain.construct_block(proof_no, last_hash) 152 | 153 | print("***Mining fccCoin has been successful***") 154 | print(blockchain.chain) 155 | --------------------------------------------------------------------------------