-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBlockchain.py
More file actions
112 lines (96 loc) · 3.8 KB
/
Blockchain.py
File metadata and controls
112 lines (96 loc) · 3.8 KB
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
from Block import Block
from BlockchainUtils import BlockchainUtils
from AccountModel import AccountModel
from ProofOfStake import ProofOfStake
class Blockchain():
def __init__(self):
self.blocks = [Block.genesis()]
self.accountModel = AccountModel()
self.pos = ProofOfStake()
def addBlock(self, block):
self.executeTransactions(block.transactions)
self.blocks.append(block)
def toJson(self):
data = {}
jsonBlocks = []
for block in self.blocks:
jsonBlocks.append(block.toJson())
data['blocks'] = jsonBlocks
return data
def blockCountValid(self, block):
if self.blocks[-1].blockCount == block.blockCount - 1:
return True
else:
return False
def lastBlockHashValid(self, block):
latestBlockchainBlockHash = BlockchainUtils.hash(
self.blocks[-1].payload()).hexdigest()
if latestBlockchainBlockHash == block.lastHash:
return True
else:
return False
def getCoveredTransactionSet(self, transactions):
coveredTransactions = []
for transaction in transactions:
if self.transactionCovered(transaction):
coveredTransactions.append(transaction)
else:
print('transaction is not covered by sender')
return coveredTransactions
def transactionCovered(self, transaction):
if transaction.type == 'EXCHANGE':
return True
senderBalance = self.accountModel.getBalance(
transaction.senderPublicKey)
if senderBalance >= transaction.amount:
return True
else:
return False
def executeTransactions(self, transactions):
for transaction in transactions:
self.executeTransaction(transaction)
def executeTransaction(self, transaction):
if transaction.type == 'STAKE':
sender = transaction.senderPublicKey
receiver = transaction.receiverPublicKey
if sender == receiver:
amount = transaction.amount
self.pos.update(sender, amount)
self.accountModel.updateBalance(sender, -amount)
else:
sender = transaction.senderPublicKey
receiver = transaction.receiverPublicKey
amount = transaction.amount
self.accountModel.updateBalance(sender, -amount)
self.accountModel.updateBalance(receiver, amount)
def nextForger(self):
lastBlockHash = BlockchainUtils.hash(
self.blocks[-1].payload()).hexdigest()
nextForger = self.pos.forger(lastBlockHash)
return nextForger
def createBlock(self, transactionsFromPool, forgerWallet):
coveredTransactions = self.getCoveredTransactionSet(
transactionsFromPool)
self.executeTransactions(coveredTransactions)
newBlock = forgerWallet.createBlock(
coveredTransactions, BlockchainUtils.hash(self.blocks[-1].payload()).hexdigest(), len(self.blocks))
self.blocks.append(newBlock)
return newBlock
def transactionExists(self, transaction):
for block in self.blocks:
for blockTransaction in block.transactions:
if transaction.equals(blockTransaction):
return True
return False
def forgerValid(self, block):
forgerPublicKey = self.pos.forger(block.lastHash)
proposedBlockForger = block.forger
if forgerPublicKey == proposedBlockForger:
return True
else:
return False
def transactionsValid(self, transactions):
coveredTransactions = self.getCoveredTransactionSet(transactions)
if len(coveredTransactions) == len(transactions):
return True
return False