-
Notifications
You must be signed in to change notification settings - Fork 2
/
chainFunctions.py
executable file
·154 lines (122 loc) · 5.1 KB
/
chainFunctions.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import time
import BlockHeader
import Transaction
import criptoFunctions
BlockHeaderChain = []
##@Roben inserted "consensus" to verify if PoW was selected
def startBlockChain():
""" Add the genesis block to the chain """
BlockHeaderChain.append(getGenesisBlock())
def createNewBlock(devPubKey, gwPvt, consensus):
""" Receive the device public key and the gateway private key then it generates a new block \n
@param devPubKey - Public key of the requesting device \n
@param gwPvt - Private key of the gateway \n
@return BlockHeader
"""
newBlock = generateNextBlock("new block", devPubKey, getLatestBlock(), gwPvt, consensus)
##@Regio addBlockHeader is done during consensus! please take it off for running pbft
#addBlockHeader(newBlock)
return newBlock
def addBlockHeader(newBlockHeader):
""" Receive a new block and append it to the chain \n
@param newBlockHeader - BlockHeader
"""
global BlockHeaderChain
BlockHeaderChain.append(newBlockHeader)
def addBlockTransaction(block, transaction):
""" Receive a block and add to it a list of transactions \n
@param block - BlockHeader \n
@param transaction - list of transaction
"""
block.transactions.append(transaction)
def getLatestBlock():
""" Return the latest block on the chain \n
@return BlockHeader
"""
global BlockHeaderChain
return BlockHeaderChain[len(BlockHeaderChain) - 1]
def getLatestBlockTransaction(blk):
""" Return the latest transaction on a block \n
@return Transaction
"""
return blk.transactions[len(blk.transactions) - 1]
def blockContainsTransaction(block, transaction):
""" Verify if a block contains a transaction \n
@param block - BlockHeader object \n
@param transaction - Transaction object\n
@return True - the transaction is on the block\n
@return False - the transcation is not on the block
"""
for tr in block.transactions:
if tr == transaction:
return True
return False
def findBlock(key):
""" Search for a specific block in the chain\n
@param key - Public key of a block \n
@return BlockHeader - found the block on the chain \n
@return False - not found the block on the chain
"""
global BlockHeaderChain
for b in BlockHeaderChain:
if (b.publicKey == key):
return b
return False
def getBlockchainSize():
""" Return the amount of blocks on the chain \n
@return int - length of the chain
"""
global BlockHeaderChain
return len(BlockHeaderChain)
def getFullChain():
""" Return the entire chain\nShowing
@return BlockHeader[] - list of all blocks on the chain
"""
return BlockHeaderChain
def getBlockByIndex(index):
""" Return the block on a specific position of the chain\n
@param index - desired block position\n
@return BlockHeader
"""
# global BlockHeaderChain
# for b in BlockHeaderChain:
# if (b.index == index):
# return b
# return False
return BlockHeaderChain[index]
def getGenesisBlock():
""" Create the genesis block\n
@return BlockHeader - with the genesis block
"""
k = """-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAM39ONP614uHF5m3C7nEh6XrtEaAk2ys
LXbjx/JnbnRglOXpNHVu066t64py5xIP8133AnLjKrJgPfXwObAO5fECAwEAAQ==
-----END PUBLIC KEY-----"""
inf = Transaction.Transaction(0, "0", "0", "0", '')
blk = BlockHeader.BlockHeader(0, "0", 1465154705, inf,
"816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7", k,0)
return blk
def generateNextBlock(blockData, pubKey, previousBlock, gwPvtKey, consensus):
""" Receive the information of a new block and create it\n
@param blockData - information of the new block\n
@param pubKey - public key of the device how wants to generate the new block\n
@param previouBlock - BlockHeader object with the last block on the chain\n
@param gwPvtKey - private key of the gateway\n
@param consensus - it is specified current consensus adopted
@return BlockHeader - the new block
"""
nextIndex = previousBlock.index + 1
nextTimestamp = time.time()
previousBlockHash = criptoFunctions.calculateHashForBlock(previousBlock)
nonce = 0
nextHash = criptoFunctions.calculateHash(nextIndex, previousBlockHash, nextTimestamp, pubKey, nonce)
if(consensus == 'PoW'):
difficulty_bits = 12 #2 bytes or 4 hex or 16 bits of zeros in the left of hash
target = 2 ** (256 - difficulty_bits) #resulting value is lower when it has more 0 in the left of hash
while ((long(nextHash,16) > target ) and (nonce < (2 ** 32))): #convert hash to long to verify when it achieve difficulty
nonce=nonce+1
nextHash = criptoFunctions.calculateHash(nextIndex, previousBlockHash, nextTimestamp, pubKey, nonce)
print("####nonce = " + str(nonce))
sign = criptoFunctions.signInfo(gwPvtKey, nextHash)
inf = Transaction.Transaction(0, nextHash, nextTimestamp, blockData, sign)
return BlockHeader.BlockHeader(nextIndex, previousBlockHash, nextTimestamp, inf, nextHash, nonce, pubKey)