-
Notifications
You must be signed in to change notification settings - Fork 1
/
blockchain.py
115 lines (87 loc) · 3.87 KB
/
blockchain.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# blockchain.py
# import the libraries required for cryptography
import hashlib
# importing date for measuring the time when the block was added to the Blockchain.
import datetime
# Note: everything will be serialized to string!
# Lets define a Transaction
class Transaction:
def __init__(self, senderAddress, recAddress, amount):
self.time = datetime.datetime.now()
self.senderAddress = senderAddress
self.recAddress = recAddress
self.amount = amount
# this is the class that defines a particular block of the blockchain
class Block:
def __init__(self, transactions,prevHash=""):
self.prevHash = prevHash
self.transactions = transactions
self.nonce = 0
self.blockHash = self.calculateHash()
self.time = datetime.datetime.now()
def calculateHash(self):
return hashlib.sha256(str( self.prevHash + str(self.transactions)+ str(self.nonce)).encode()).hexdigest()
#mining the block, else any spammer can create multiple blocks without validation!!
def mineBlock(self):
while (self.blockHash[0:4]!="0000"):
self.nonce +=1
self.blockHash = self.calculateHash()
#adeesh+nonce => adjfnkldjfmal;dsjfads ==> 0000kdsfnkadnfklsn
# this is the class that defines the blockchain
class BlockChain:
def __init__(self):
# only property of the blockchain is the chain
self.chain = [self.createGenesis()]
self.peningTransactions = []
self.miningReward = 100
# the first block of the blockchain should be added manually
def createGenesis(self):
return Block([Transaction("Genesis", "Genesis",21000000000)], "Genesis")
# function to get the latest block
def getLatestBlock(self):
return self.chain[-1]
# Mining pending transactions and adding the block!
def minePendingTransactions(self, receiverAddress):
newBlock = Block( self.peningTransactions, self.getLatestBlock().blockHash)
newBlock.mineBlock()
self.chain.append(newBlock)
self.peningTransactions = [Transaction("Genesis",receiverAddress,self.miningReward)]
# verifying the blockchain
def isValid(self):
for i in range(1,len(self.chain)):
currentBlock = self.chain[i]
prevBlock = self.chain[i-1]
# check if the blockHash is valid and has not been tampered
if(currentBlock.blockHash != currentBlock.calculateHash()):
return False, "hash issue", i
if(currentBlock.prevHash != prevBlock.blockHash):
return False, "chain issue"
return True
def createTransaction(self,transaction):
if(transaction.amount>self.getBalanceof(transaction.senderAddress) and transaction.senderAddress!="Genesis"):
print("not enough balance")
return False
self.peningTransactions.append(transaction)
return True
# get the current balance of an account
def getBalanceof(self, address):
balance = 0
for block in self.chain:
for transaction in block.transactions:
if(transaction.senderAddress == address):
balance -= transaction.amount
if(transaction.recAddress == address):
balance += transaction.amount
return balance
def getUserTransactionHistory(self,user):
a=[]
for blocks in self.chain:
for transaction in blocks.transactions:
if (transaction.senderAddress == user or transaction.recAddress == user):
a.append(transaction)
return a
def checkIfUserHasPendingTransanctions(self,user):
for transaction in self.peningTransactions:
if(transaction.senderAddress== user):
return True
return False