Last active
July 14, 2022 13:49
-
-
Save reachjason/560d30b94bbd3c5c7f1edd9f98654539 to your computer and use it in GitHub Desktop.
Implementing a Blockchain in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Import statements | |
import hashlib | |
import datetime | |
class Block: | |
''' | |
All blocks contain the following data: | |
block_height -> index of block on chain | |
data -> data in the block | |
hash -> hash of this block | |
previous_hash -> hash of the previous block | |
timestamp -> time the block was added to the chain | |
nonce -> number that miners are trying to solve for | |
they get rewarded. Default = 0 | |
''' | |
# Block instance attributes | |
def __init__(self, index, data, previous_hash, timestamp, nonce=0): | |
self.index = index | |
self.timestamp = timestamp | |
self.data = data | |
self.previous_hash = previous_hash | |
self.nonce = nonce | |
self.hash = self.hash_block() | |
# Block description | |
def __str__(self): | |
return(f"This is a block") | |
''' | |
defining a function that computes the hash of | |
the block based on the attributes. | |
Takes in no inputs. | |
Creates a string of all the class variables. | |
Computes SHA256 hash of the string. | |
''' | |
def hash_block(self): | |
#block_data = str(self.index) + self.timestamp + self.data + self.previous_hash + self.nonce | |
block_data = str(self.index) + str(self.timestamp) + self.data + self.previous_hash | |
# encoding block data to utf8 - needed before hashing | |
block_data = block_data.encode('utf8') | |
# create a sha256 hash object | |
hash = hashlib.sha256() | |
# feeding blockdata to the hash object | |
hash.update(block_data) | |
# return the output as the digest of the hash | |
return(hash.hexdigest()) | |
def test_blockchain(index, time, data, previous_hash): | |
new_block = Block(index, data, previous_hash, time) | |
#check_string = "2def27922fc1c67254a9cdb0c660b91abf9b135ad38fc13c7c77007448b824a0" | |
check_string = "687102d55b610a7a7271fdf2ac15c746009fa4909a6d8a375cc1bca72a83dc47" | |
# print(str(new_block.hash)) | |
if(str(new_block.hash) == check_string): | |
print_statement = "Pass" | |
else: | |
print_statement = "Fail" | |
print(print_statement) | |
time = '2021-05-22 04:20:20' | |
data = "Jason's blockchain on Python" | |
previous_hash = '323fdb2771a9e5cc34ebc3d44c8888fa4bca31ce4a276523ba29cf3da0668b58' | |
index = 0 | |
# create a new Block | |
# block1 = Block(index, data, previous_hash, time ) | |
# print(block1.hash) | |
test_blockchain(index, time, data, previous_hash) | |
''' | |
Implementing other functions for the blockchain | |
1. create_genesis_block() - first block in the chain | |
3. next_block() - | |
''' | |
def create_genesis_block(): | |
''' | |
This function creates the first block in the chain | |
''' | |
index = 0 # since it is the first block | |
timestamp = datetime.datetime.now() # depends on when it is called | |
data = "Jason's Genesis Block" | |
previous_hash = "0" | |
return(Block(index, data, previous_hash, timestamp)) | |
def next_block(last_block, nonce=0): | |
''' | |
uses the last block (object) | |
returns a new instance of class Block where | |
index = index of last_block + 1 | |
timestamp = Now | |
data = "This is block {index}" | |
previous_hash = hash of last_block | |
''' | |
index = last_block.index + 1 | |
#timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
timestamp = datetime.datetime.now() | |
data = f"This is block {index}" | |
previous_hash = last_block.hash | |
return(Block(index, data, previous_hash, timestamp, nonce)) | |
def test_next_block(genesis_block): | |
block_1 = next_block(genesis_block) | |
if block_1.index == 1 and block_1.data == "This is block 1" and block_1.previous_hash == genesis_block.hash and str(type(block_1.timestamp)) == "<class 'datetime.datetime'>": | |
print("Pass") | |
else: | |
print("Fail") | |
# testing genesis block creation | |
genesis_block = create_genesis_block() | |
test_next_block(genesis_block) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment