-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblockchain.py
148 lines (114 loc) · 3.41 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
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
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Project File: Python 2.x or 3.x
__author__ = "Adam Dabdoub"
__copyright__ = "Copyright 2021, Dabdoub"
__credits__ = ["Adam Dabdoub"]
__developers__ = ["adamdabdoub "]
__license__ = "GPL"
__version__ = "1.0."
__maintainer__ = "Adam Dabdoub"
__email__ = "[email protected]"
__status__ = "Production"
#IMPORTS
from hashlib import sha256
"""blockchain.py incorporates cryptography
into python.
Example:
blockchain = Blockchain()
block = Block("some data",1)
blockchain.mine(block)
print(blockchain.chain)
"""
#get the update hash of arguments
def updatehash(*args):
hashing_text = ""; h = sha256()
for arg in args:
hashing_text += str(arg)
h.update(hashing_text.encode('utf-8'))
return h.hexdigest()
#block object definition
class Block():
data = None
hash = None; nonce = 0
previous_hash = "0" * 64
#specify data and block number on instance
def __init__(self,data,number=0):
self.data = data
self.number = number
#hash a block using updatehash
def hash(self):
return updatehash(
self.previous_hash,
self.number,
self.data,
self.nonce
)
#when printing a block
def __str__(self):
return str("Block#: %s\nHash: %s\nPrevious:" +
" %s\nData: %s\nNonce: %s\n" %(
self.number,
self.hash(),
self.previous_hash,
self.data,
self.nonce
)
)
#blockchain object definition
class Blockchain():
difficulty = 4
#specify previous blockchain on instance
def __init__(self,chain=[]):
self.chain = chain
#add a block to the chain
def add(self, block):
self.chain.append({
'hash': block.hash(),
'previous': block.previous_hash,
'number': block.number,
'data': block.data,
'nonce': block.nonce
})
#find the correct nonce to satisfy the difficulty
def mine(self, block):
try: block.previous_hash = self.chain[-1].get('hash')
except IndexError: pass
while True: #loop until correct nonce found
if block.hash()[:self.difficulty] == "0" * self.difficulty:
self.add(block); break
else:
block.nonce += 1
#find if a list is the majority of other lists
def ismajority(item,p,lists):
counter = 0
for l in lists:
if l[p] == item:
counter +=1
if counter > len(lists)/2:
return True
#get a list of the valid blockchains
def getvalidblockchains(chains):
invalid_chains = []; valid_chains = []
for blockchain in chains:
for i in range(len(blockchain)):
if not ismajority(blockchain[i],i,chains):
invalid_chains.append(blockchain); break
if blockchain not in invalid_chains:
valid_chains.append(blockchain)
return valid_chains
#testing the blockchain
if __name__ == '__main__':
test_1 = ["hello","bye","word"]
test_2 = ["hello","bye","word"]
test_3 = ["hello","no","word"]
test_4 = ["wait","bye","hey"]
lists = [test_1,test_2,test_3,test_4]
print(getvalidblockchains(lists))
blockchain = Blockchain()
database = ["hello","bye","hey"]
num = 0
for data in database:
num += 1
blockchain.mine(Block(data, num))
print(blockchain.chain)