|
| 1 | +import time, hashlib, json |
| 2 | + |
| 3 | + |
| 4 | +""" |
| 5 | +Created by trustgeek on 2017-10-23 (11:04). |
| 6 | +""" |
| 7 | + |
| 8 | +class Block: |
| 9 | + def __init__(self, index, timestamp, data, previous_hash): |
| 10 | + self._index = index |
| 11 | + self._timestamp = timestamp |
| 12 | + self._data = data |
| 13 | + self._previous_hash = previous_hash |
| 14 | + self._nounce = None |
| 15 | + self._hash = self.hash() |
| 16 | + |
| 17 | + def valid_hash(self, the_hash): |
| 18 | + return the_hash.startswith('0000') |
| 19 | + |
| 20 | + def mined(self): |
| 21 | + return self._nounce is not None |
| 22 | + |
| 23 | + def mine(self): |
| 24 | + start_time = time.time() |
| 25 | + the_nounce = self._nounce or 0 |
| 26 | + while True: |
| 27 | + the_hash = self.hash(nonce=the_nounce) |
| 28 | + if self.valid_hash(the_hash): |
| 29 | + self._hash = the_hash |
| 30 | + self._nounce = the_nounce |
| 31 | + end_time = time.time() |
| 32 | + time_taken = end_time - start_time |
| 33 | + print("----- Mine time: %s -----" % time_taken) |
| 34 | + return |
| 35 | + else: |
| 36 | + the_nounce += 1 |
| 37 | + |
| 38 | + def hash(self, nonce=None): |
| 39 | + self._nounce = nonce or self._nounce |
| 40 | + block_json = {'index': self._index, 'timestamp': self._timestamp, 'data': self._data, |
| 41 | + 'previous_hash': self._previous_hash, 'nounce': self._nounce} |
| 42 | + |
| 43 | + return hashlib.sha256(json.dumps(block_json).encode('utf-8')).hexdigest() |
| 44 | + |
| 45 | + def __str__(self): |
| 46 | + return json.dumps( |
| 47 | + {'index': self._index, 'timestamp': self._timestamp, 'data': self._data, |
| 48 | + 'previous_hash': self._previous_hash, |
| 49 | + 'hash': self._hash, 'nounce': self._nounce}) |
| 50 | + |
| 51 | + |
| 52 | +# genesis block is the first block in the blockchain |
| 53 | +def genesis_block(): |
| 54 | + return Block(0, time.time(), "This is genesis block", '0') |
| 55 | + |
| 56 | + |
| 57 | +# create next block for blockchain |
| 58 | +def next_block(_previous_block, data): |
| 59 | + _new_index = _previous_block._index + 1 |
| 60 | + _new_timestamp = time.time() |
| 61 | + _previous_hash = _previous_block._hash |
| 62 | + return Block(_new_index, _new_timestamp, data, _previous_hash) |
| 63 | + |
| 64 | + |
| 65 | +blockchain = [genesis_block()] |
| 66 | + |
| 67 | +# first block for blockchain |
| 68 | +previous_block = blockchain[0] |
| 69 | +num_of_blocks = 20 |
| 70 | + |
| 71 | +# iteratively adding block to blockchain |
| 72 | +for i in range(0, num_of_blocks): |
| 73 | + transaction = {'from': '0x12345' + str(i), 'to': '0x54321' + str(i * 3), 'amount': 100} |
| 74 | + new_block = next_block(previous_block, transaction) |
| 75 | + new_block.mine() |
| 76 | + blockchain.append(new_block) |
| 77 | + previous_block = new_block |
| 78 | + print("Block added to blockchain") |
| 79 | + print(new_block) |
0 commit comments