

from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
import json
from base64 import b64encode, b64decode
from time import time

class Blockchain:
    def __init__(self):
        self.current_transactions = [] #egy list amiben tároljuk az aktuális tranzakciókat.
        self.chain = [] #egy list amiben a blockchaint tároljuk
        
        
        key = self.read_key()
        
        
        
        self.private_key = key #kiolvassuk a saját kulcsunkat a fájlból amit korábban létrehoztunk
        self.public_key= key.publickey() #itt is
        
        self.my_inputs = [
            {'signature': 'valami_aláírás_van_itt_1', 'amount': 10.1},
            {'signature': 'valami_aláírás_van_itt_2', 'amount': 0.1},
            {'signature': 'valami_aláírás_van_itt_3', 'amount': 5},
            {'signature': 'valami_aláírás_van_itt_4', 'amount': 4.13},
        ] # egy segédlista a saját bejövő tranzakcióimról. Nem muszáj igazából, most csak azért van itt, hogy legyen min gyakorolni
          #sőt igazából itt mivel az aláírás az minden tranzakciónál egyedi, ezért a kulcs-érték pár lehetne az aláírás-érték pár, de a könnyebb átláthatóság kedvéért most így lesz


    def sign_data(self, data): #mivel itt már használjuk a saját privát kulcsot, ezért ez nem staticmethod.
    #todo megírni a belsejét a net alapján. Először hasheljük az adatot és a hash-t írjuk alá (az aláírást az importált PKCS1_v1_5 alapján csináljátok)

        hash = self.hash(data)
        signature = PKCS1_v1_5.new(self.private_key).sign(hash)
    
        
        return b64encode(signature)


    def verify(self, data, signature, pub_key): #Itt nézzétek meg a paramétereket és értsétek meg, hogy melyik paraméter miért kell az aláírás ellenőrzéséhez
        #megírni a függvény belsejét
        
        signature = b64decode(signature)
        
        hash = Blockchain.hash(data)
        verifier = PKCS1_v1_5.new(pub_key)
        
        if verifier.verify(hash, signature):
            return True
        else:
            return False

        
    @staticmethod
    def generate_key():

        key = RSA.generate(2048)
        encrypted_key = key.exportKey('PEM');

        file_out = open("rsa_key.PEM", "wb")
        file_out.write(encrypted_key)
        
    @staticmethod 
    def read_key():
        #secret_code = "Unguessable"
        encoded_key = open("rsa_key.PEM", "rb").read()
        key = RSA.import_key(encoded_key)

        #print(key.publickey().exportKey())
        return key
       
    @staticmethod
    def hash(data):
        hash = SHA256.new()
        encoded_data = json.dumps(data, sort_keys=True).encode()
        hash.update(encoded_data)
        return hash



bc = Blockchain()
data = "hello"
signature = bc.sign_data(data)
data = "hello"
print(bc.verify(data, signature, bc.public_key))
data = "Szia Laci"
print(bc.verify(data, signature, bc.public_key))


# jegyzőkönyvbe:
# -kriptovaluta működése - mese a gyak elejéről (blockchain, blokkok linkelése, stb.)
# - melyik függvény mit csinálj: mi a hash, mi a SHA256, mire való
# - mi a kulcs, mi a PEM formátum, mi az RSA, hogy működik
# - mi az az aláírás miért biztos
# - mit csináltunk gyakon
# - kód mehet bele, de nem muszáj
