Пример #1
0
 def __init__(self, blockchain, address):
     self.blockchain = blockchain
     self.address = address
     self.relay = RelayClient()
     self.updater = Updater(self.blockchain, self.relay)
     self.flag = 0
     self.index = 0
Пример #2
0
class Miner:
    FLAG = 1e6  #number of iteration of mining before check if the block has been found

    def __init__(self, blockchain, address):
        self.blockchain = blockchain
        self.address = address
        self.relay = RelayClient()
        self.updater = Updater(self.blockchain, self.relay)
        self.flag = 0
        self.index = 0

    def create_block(self):
        self.block = Block(self.blockchain.get_last_hash(), self.address)
        self.block.set_transactions(self.get_transactions())
        self.index = 0

    def get_transactions(self):
        """Allow to choose wich transactions will be placed in the block
        For now, it just take them in the chronological order"""
        ts = self.relay.get_transactions()
        if ts is None:
            return []
        # filter invalid transactions
        ts = list(filter(lambda t: t.is_valid(self.blockchain), ts))
        # transactions can be valid alone and invalid together
        # (e.g. 2 transactions with same sender)
        if not self.block.valid_transactions(self.blockchain):
            self.block.set_transactions([])
        # TODO: sort as you want (fee ?)
        return ts

    def run(self, strategy):
        """Strategy is the function called to find the next PoW"""
        print('Mining for address ' + str(self.address) + ' ', end='')
        self.create_block()
        while (1):
            if self.flag == 0:  # check relay for new block
                self.flag = Miner.FLAG
                if self.updater.update():
                    print('Downloaded new block')
                    print('Mining for address ' + str(self.address) + ' ',
                          end='')
                    self.create_block()
                print('.', end='', flush=True)  # show state to the user
            self.flag = self.flag - 1
            self.block.set_proof(strategy(self.index))
            self.index = self.index + 1
            if (self.block.good_difficulty()):
                print('\nMined block ' + self.block.get_hash())
                self.relay.submit_block(self.block)
                self.flag = 0  #Need to take new transactions
Пример #3
0
 def __init__(self, server_address, blockchain):
     super().__init__(server_address, RelayHandler)
     self.blockchain = blockchain
     self.master = MasterClient()
     self.transactions = []
     # HTTP client relays, used to broadcast transactions
     self.relays = []
     for r in Network.get_relays():
         if r != server_address:
             self.relays.append(RelayClient(r))
     print('Server started on ' + server_address[0] + ':' +
           str(server_address[1]))
Пример #4
0
class Updater(object):
    def __init__(self, blockchain, relay=None):
        self.blockchain = blockchain
        if relay is None:
            self.relay = RelayClient()
        else:
            self.relay = relay

    def update(self):
        """Update the blockchain from relay
           Stop when blockchain is updated (next block is None)
           Return True if updated, False if not
        """
        debug('updating blockchain')
        updated = False
        new_block = self.relay.get_block(self.blockchain.get_last_hash())
        while not new_block is None:
            debug('got block ' + new_block.get_hash())
            updated = True
            self.blockchain.add_block(new_block)
            new_block = self.relay.get_block(self.blockchain.get_last_hash())
        return updated
Пример #5
0
    def __init__(self, user_ID, password):
        """Create a new wallet

        user_ID  : The ID of the user to select it's own address on the DB
        password : The password is used to generate a AES_Key to ecrypt / decrypt the private key on DB
                   Here, we used it to load all the address or write the new address
        """
        self.blockChain = Blockchain('client')
        self.relay = RelayClient()
        self.updater = Updater(self.blockChain, self.relay)
        self.updater.update()
        self.user_ID = user_ID
        self.addrList = loadAddressList(self.user_ID)  # list of address
        self.last = len(self.addrList) - 1  #index of the actual address
        if self.addrList == []:  #New Wallet : Create the first Address
            self.addr = Address()
            self.addr.encryptPrivateKey(password)
            add_address(self.user_ID, self.addr, 0)
            self.addrList.append(self.addr)
        else:
            self.addr = self.addrList[len(self.addrList) - 1]
        self.count = self.blockChain.get_amount_of_address(self.addr)
Пример #6
0
 def __init__(self, blockchain, relay=None):
     self.blockchain = blockchain
     if relay is None:
         self.relay = RelayClient()
     else:
         self.relay = relay
Пример #7
0
    if relay.submit_transaction(t):
        print('transaction sent to the network')
    else:
        print('error sending transaction')


def usage():
    exit('usage: python3 '+av[0]+' list|new|transfer')

if __name__ == '__main__':
    # init database
    db.createDB()
    
    # always update blockchain
    bc = Blockchain('client')
    relay = RelayClient()
    u = Updater(bc, relay)
    print('updating blockchain ...')
    u.update()
    
    # parse arguments
    av = sys.argv
    ac = len(av)
    if ac == 1:
        usage()
    
    if av[1] == 'list':
        display_addresses(bc)
    elif av[1] == 'new':
        create_address()
    elif av[1] == 'transfer':
Пример #8
0
class Wallet(object):
    """Wallet is the principal user
    Wallet have money and can create some Transaction to send money to an another Wallet
    """
    def __init__(self, user_ID, password):
        """Create a new wallet

        user_ID  : The ID of the user to select it's own address on the DB
        password : The password is used to generate a AES_Key to ecrypt / decrypt the private key on DB
                   Here, we used it to load all the address or write the new address
        """
        self.blockChain = Blockchain('client')
        self.relay = RelayClient()
        self.updater = Updater(self.blockChain, self.relay)
        self.updater.update()
        self.user_ID = user_ID
        self.addrList = loadAddressList(self.user_ID)  # list of address
        self.last = len(self.addrList) - 1  #index of the actual address
        if self.addrList == []:  #New Wallet : Create the first Address
            self.addr = Address()
            self.addr.encryptPrivateKey(password)
            add_address(self.user_ID, self.addr, 0)
            self.addrList.append(self.addr)
        else:
            self.addr = self.addrList[len(self.addrList) - 1]
        self.count = self.blockChain.get_amount_of_address(self.addr)

    def backAddress(self):
        """Return to the previous address
        """
        if len(self.addrList) >= 2:
            self.addr = self.addrList[len(addrList) - 2]
            self.addrList.pop(self.addrList[len(self.addrList) - 1])

    def checkUpdate(self):
        """Update the amount and the blockChain
        """
        self.updater.update()
        self.count = self.blockChain.get_amount_of_address(self.addr)

    def createTransaction(self, password, destList):
        """Create a new transaction and send it to the RelayNode
           destList is a list of tuples
           Each tuples is like : (str_address, value)
           The last transaction is the rest of the wallet send to the new user address
        """
        self.checkUpdate()
        newAddr = Address()
        newAddr.encryptPrivateKey(password)
        total = sum([i[1] for i in destList])
        if total <= self.count:
            destList.append((str(newAddr), (self.count - total)))
            transac = Transaction(self.addr.public(), destList)
            self.addr.decryptPrivateKey(password)
            transac.sign(self.addr)
            debug('valid: ' + ('True' if transac.is_signed() else 'False'))
            self.addr.encryptPrivateKey(password)
            if not self.relay.submit_transaction(transac):
                return False
            self.addrList.append(newAddr)
            self.addr = newAddr
            add_address(self.user_ID, self.addr, len(self.addrList) - 1)
            return True
        else:
            return False