-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblockchain.py
180 lines (155 loc) · 6.34 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
from time import time
import datetime
import os
import pickle
import hashlib as hasher
import acoustic.acoustid_check as ac
import text_compare.test_text as tc
import image_compare.image_check as ic
""" Class for transactions made on the blockchain. Each transaction has a
sender, recipient, and value.
"""
class Transaction:
""" Transaction initializer """
def __init__(self, title="", filename="", author="", public_key="", genre="", media = ""):
self.title = title
self.filename = filename
self.author = author
self.public_key = public_key
self.genre = genre
self.media = media
""" Converts the transaction to a dictionary """
def toDict(self):
return {
'title': self.title,
'filename': self.filename,
'author': self.author,
'public_key': self.public_key,
'genre': self.genre,
'media': self.media,
}
def __str__(self):
toString = self.author + " : " + self.genre + " (" + self.media + ") "
return toString;
""" Class for Blocks. A block is an object that contains transaction information
on the blockchain.
"""
class Block:
def __init__(self, index, transaction, previous_hash):
self.index = index
self.timestamp = time()
self.previous_hash = previous_hash
self.transaction = transaction
def compute_hash(self):
concat_str = str(self.index) + str(self.timestamp) + str(self.previous_hash) + str(self.transaction['author']) + str(self.transaction['genre'])
hash_result = hasher.sha256(concat_str.encode('utf-8')).hexdigest()
return hash_result
def serialize(self):
return {
'index': self.index,
'timestamp': self.timestamp,
'previous_hash': self.previous_hash,
'transaction': self.transaction
}
""" Blockchain class. The blockchain is the network of blocks containing all the
transaction data of the system.
"""
class Blockchain:
def __init__(self):
self.unconfirmed_transactions = {}
self.chain = []
def create_genesis_block(self):
empty_media = {
'title': "",
'filename': "",
'author': "",
'public_key': "",
'genre': "",
'media': "",
}
new_block = Block(index=0, transaction=empty_media, previous_hash=0)
self.add_block(new_block)
return new_block
def new_transaction(self, title, filename, author, public_key, genre, media):
new_trans = Transaction(title, filename, author, public_key, genre, media).toDict();
self.unconfirmed_transactions= new_trans.copy()
return new_trans
def mine(self):
#create a block, verify its originality and add to the blockchain
if (len(self.chain) ==0):
block_idx = 1
previous_hash = 0
else:
block_idx = self.chain[-1].index + 1
previous_hash = self.chain[-1].compute_hash()
block = Block(block_idx, self.unconfirmed_transactions, previous_hash)
if(self.verify_block(block)):
self.add_block(block)
return block
else:
return None
def verify_block(self, block):
#verify song originality and previous hash
#check previous hash
if len(self.chain) ==0:
previous_hash = 0
else:
previous_hash = self.chain[-1].compute_hash()
if block.previous_hash != previous_hash:
return 0
#check originality
for prev_block in self.chain:
if block.transaction['genre'] == prev_block.transaction['genre']:
try:
if block.transaction['genre'] == 'Audio':
score = ac.calc_accuracy('./uploads/' + block.transaction['media'], './uploads/' + prev_block.transaction['media'])
print(score)
if score > 0.9:
return 0
if block.transaction['genre'] == 'Text':
score = tc.check_text_similarity('./uploads/' + block.transaction['media'], './uploads/'+prev_block.transaction['media'])
print(score)
if score < 100:
return 0
if block.transaction['genre'] == "Image":
score = ic.calc_accuracy('./uploads/' + block.transaction['media'], './uploads/' + prev_block.transaction['media'])
print(score)
if score < 0.4:
return 0
except:
return 0
return 1
def lookup(self, transaction):
#check originality
for prev_block in self.chain:
if transaction['genre'] == prev_block.transaction['genre']:
try:
if transaction['genre'] == 'Audio':
score = ac.calc_accuracy('./tmp/' + transaction['media'], './uploads/' + prev_block.transaction['media'])
print(score)
if score > 0.9:
return prev_block
if transaction['genre'] == 'Text':
score = tc.check_text_similarity('./tmp/' + transaction['media'], './uploads/'+prev_block.transaction['media'])
print(score)
if score < 100:
return prev_block
if transaction['genre'] == "Image":
score = ic.calc_accuracy('./tmp/' + transaction['media'], './uploads/' + prev_block.transaction['media'])
print(score)
if score < 0.4:
return prev_block
except:
print("exception")
return prev_block
return None
def add_block(self, block):
self.chain.append(block)
with open('./blockchain/chain.pkl', 'wb') as output:
pickle.dump(self.chain, output, pickle.HIGHEST_PROTOCOL)
def check_integrity(self):
return 0
""" Function that returns the last block on the chain"""
@property
def last_block(self):
return self.chain[-1]