Beispiel #1
0
def create_block():

    with open(parentdir + "/core" + "/key.pem") as f:
        key = RSA.importKey(f.read())
    """ First transaction for first block """
    trans1 = {
        "vin": [None],  # First transaction
        "vout": [{
            "amount": 1000000.0,
            "address": key.publickey().exportKey().decode()
        }]
    }
    trans1["txid"] = sha(json.dumps(trans1))

    block1 = {
        "header": {
            "prev_block_hash": None,
            "merkle_root": None,
            "timestamp": None,
            "nonce": None,
            "difficulty_target": "0"
        },
        "transactions": [trans1]
    }

    utxo = UTXO()
    blockdb = Blockdb()

    blockdb.add_block(block1)
    utxo.add_trans(block1['transactions'], sha(json.dumps(block1['header'])))
Beispiel #2
0
    def req_block(self, conn):
        """
        conn : socket object
            the connection with the longest chain

        Send the hash of the latest block all nodes will send back the 
        number of missing blocks, this node will extend using the longest chain
        method
        """

        latest = self.blockdb.get_latest()
        conn.send("GET_BLOCKS".encode())
        conn.send(str(latest).encode())
        num_blocks = int(conn.recv(1024).decode())

        block_num = 1
        while block_num <= num_blocks:
            block_size = int(conn.recv(1024).decode())
            block = conn.recv(1024)

            while len(block) < block_size:
                block += conn.recv(1024)

            block = json.loads(block.decode())
            self.utxo.add_trans(block['transactions'], sha(json.dumps(block)))
            self.blockdb.add_block(block)  ## DOESNT VARIFY THE BLOCK
            block_num += 1
        print("Blockchain Updated")
Beispiel #3
0
    def new_trans(self, amount, recepient):
        """
        amount : float
            the total payment to the recepient
        recepient : str
            the public key address of the receiving party
            
        returns: json
            a json data structure with input/output information of the transaction
        """

        trans, change = self._get_unspent(amount)

        vin = []
        for t in trans:
            sig = self.sign(t[1])  # sign transaction id
            vin.append({
                'txid': t[1],  # (id, txid, address, change, amount, block)
                'change': t[3],  # boolean 0 or 1
                'sig': sig,
            })

        vout = [{"amount": amount, "address": recepient}]

        if change > 0:
            vout.append({
                "amount": change,
                "address": self.key.publickey().exportKey().decode()
            })

        data = {"vin": vin, "vout": vout}

        data['txid'] = sha(json.dumps(data))  # hashes the transaction
        self.broadcast(data)
Beispiel #4
0
    def add_block(self, block):

        block_hash = sha(json.dumps(block['header']))
        # check if block is already saved
        get_block = self.get_block_by_hash(block_hash)
        if get_block != None:
            return None

        block_num = self.get_latest()
        if block_num == None:
            block_num = 1
        else:
            block_num += 1

        file = f"/block_{block_num}.json"
        # save the block as a file
        with open(parentdir + "/blocks" + file, "w") as f:
            json.dump(block, f)

        # add block to hash-table database
        with self.conn:
            self.c.execute("INSERT INTO blocks VALUES (NULL, :hash, :file)", {
                'hash': block_hash,
                'file': f'block_{block_num}.json'
            })
Beispiel #5
0
 def verify_pow(self, header):
     
     diff = header["difficulty_target"]
     hashed = sha(json.dumps(header))
     if hashed[:len(diff)] == diff:
         return True
     else:
         return False
Beispiel #6
0
 def verify_prev_block(self, header):
     
     block_num = self.get_block_num()
     with open(self.path + f"/block_{block_num}.json") as f:
         block = json.load(f)
         
     hashed = sha(json.dumps(block['header']))
     if hashed == header['prev_block_hash']:
         return True
     else:
         return False
Beispiel #7
0
    def merkle_root(self, leaves):

        num_leaves = len(leaves)
        if num_leaves == 1:
            if type(leaves[0]) == dict: # For blocks with a single transaction
                return sha(json.dumps(leaves[0]))
            else:
                return leaves[0]
        
        parent = [ ]
        i = 0
        while i < num_leaves:
            left = sha(json.dumps(leaves[i]))
            if (i + 1) < num_leaves:
                right = sha(json.dumps(leaves[i + 1]))
            else:
                right = sha(json.dumps(leaves[i]))
                
            parent.append(sha(left + right))
            i += 2
        return self.merkle_root(parent)
Beispiel #8
0
 def proof_of_work(self, merkle_root):
     
     hashed = "1" * len(self.diff)
     while hashed[:len(self.diff)] != self.diff:
         header = {
                     "prev_block_hash": self.prev_block_hash,
                     "merkle_root": merkle_root,
                     "timestamp": str(datetime.datetime.now().isoformat()),
                     "nonce": str(random.getrandbits(32)),
                     "difficulty_target": self.diff
                  }
         hashed = sha(json.dumps(header))
     return header
Beispiel #9
0
    def new_block(self, conn, block):

        utxo = UTXO()
        blockdb = Blockdb()
        # check if block is already in the local chain
        exists = blockdb.get_block_by_hash(sha(block))
        if exists != None:
            return None
        # ensure the block is valid
        if not self.verify("block", block):
            return None
        logging.debug("New block verified")
        # remove all transaction in the block from unconfirmed pool
        self.pool.check_new_block(sha(block))
        # add all transaction outputs to utxo
        utxo.add_trans(block['transactions'], sha(json.dumps(block)))
        # remove all inputs from utxo
        utxo.remove_trans(block['transactions'])
        # save block in Blockdb
        blockdb.add_block(block)
        # propogate block
        self.client.prop_block(json.dumps(block).encode())
Beispiel #10
0
 def verify_hash(self, trans):
     """ trans : dict
             transaction data structure
             
         returns : boolean
             True if txid matches the hash of the transaction
     """
     
     tcopy = trans.copy()
     del tcopy['txid']
     hashed = sha(json.dumps(tcopy))
     
     if trans['txid'] == hashed:
         return True
     else:
         return False