Beispiel #1
0
    def solve_on_thread(self):
        """ solves the POW and creates a new coinbase transaction when solved. """
        self.coinbase = CoinBase()
        self.transactions.append(self.coinbase)
        self.b = Block()
        result = self.solve_proof_of_work()
        if self.start_over:
            self.start_over = False
            log.debug('Mining stopped')
            self.isMining = False
            return
        if result:
            self.transactions = []
            log.info('Block solution found!, %d', self.b.nonce)
            self.client.broadcast_info('Block solution found')
            log.info('Block hash: %s',
                     self.b.hash_block(hex=True, withoutReward=False))
            self.broadcast_info('Block solution found!')
            if self.start_over:
                self.start_over = False
                self.isMining = False
                log.debug('Mining stopped')
                return

            self.coinbase.finish_transaction()
            self.b.finish_block()
            self.isMining = False
Beispiel #2
0
 def solve_on_thread(self):
   """ solves the POW and creates a new coinbase transaction when solved. """
   self.coinbase = CoinBase()
   self.transactions.append(self.coinbase)
   self.b = Block()
   result = self.solve_proof_of_work()
   if self.start_over:
       self.start_over = False
       log.debug('Mining stopped')
       self.isMining = False
       return
   if result:
     self.transactions = []
     log.info('Block solution found!, %d', self.b.nonce)
     self.client.broadcast_info('Block solution found')
     log.info('Block hash: %s', self.b.hash_block(hex=True, withoutReward=False))
     self.broadcast_info('Block solution found!')
     if self.start_over:
       self.start_over = False
       self.isMining = False
       log.debug('Mining stopped')
       return
     
     self.coinbase.finish_transaction()
     self.b.finish_block()
     self.isMining = False
Beispiel #3
0
 def initApp(self):
   #Connect Here
   self.client = P2PClientManager.getClient(port=random.randint(40000, 60000))
   self.client.subscribe(Message.NEW_TRANSACTION, self.update_balance)
   self.client.subscribe_to_info(self.update_status)
   t = threading.Thread(target=self.start_miner)
   t.start()
   if not self.db.hasRanBefore():
     c = CoinBase(owner=KeyStore.getPrivateKey(), amt=100)
     c.finish_transaction()
     self.db.setRanBefore()
     #messagebox.showinfo('Welcome', 'This is your first time running the app. You get to start off with 100 PyCoins!')
   #Get balance, Save to variable below
   self.coin_balance.set(str(KeyStore.get_balance()))
   print('PyCoin Address: ', SHA.new(KeyStore.getPublicKey().exportKey()).hexdigest())
   log.debug("GUI created")
Beispiel #4
0
class Miner:
  
  INVALID = -1
  
  def __init__(self):
    """ initializes the miner object """
    self.hashnum = SHA256.new()
    self.transactions = []
    self.start_over = False
    self.isMining = False
    
    self.client = P2PClientManager.getClient()
    self.client.subscribe(Message.NEW_BLOCK, self.handle_new_block)
    self.client.subscribe(Message.NEW_TRANSACTION, self.handle_new_transaction)
    self.mining_thread = None

  def handle_new_transaction(self, trans):
    """ a callback function that is called when a new transaction is received
    from the p2p client

    params:
      trans -> the new transaction
    """
    if not isinstance(trans, Transaction):
      raise Exception('Not a Transaction object!')
    self.transactions.append(trans)
    log.debug('Received new transaction')
    if len(self.transactions) > 5 and not self.isMining:
      self.mining_thread = threading.Thread(target=self.solve_on_thread)
      self.mining_thread.start()
        
  def solve_on_thread(self):
    """ solves the POW and creates a new coinbase transaction when solved. """
    self.coinbase = CoinBase()
    self.transactions.append(self.coinbase)
    self.b = Block()
    result = self.solve_proof_of_work()
    if self.start_over:
        self.start_over = False
        log.debug('Mining stopped')
        self.isMining = False
        return
    if result:
      self.transactions = []
      log.info('Block solution found!, %d', self.b.nonce)
      self.client.broadcast_info('Block solution found')
      log.info('Block hash: %s', self.b.hash_block(hex=True, withoutReward=False))
      self.broadcast_info('Block solution found!')
      if self.start_over:
        self.start_over = False
        self.isMining = False
        log.debug('Mining stopped')
        return
      
      self.coinbase.finish_transaction()
      self.b.finish_block()
      self.isMining = False
      
  def handle_new_block(self, block):
    """ a callback method that will be called when a new block is received
    from the p2p client.

    params:
      block -> the new block
    """
    log.debug('Received new block')
    self.start_over = True
    self.remove_queue_transactions(block)
    self.isMining = False
    
  def remove_queue_transactions(self, block):
    """ removes any transactions from the queue that were
    already included in the incoming block

    params:
      block -> the received block
    """
    toBeRemoved = []
    for t in block.transactionList:
      for trans in self.transactions:
        if t.hash_transaction() == trans.hash_transaction():
          toBeRemoved.append(trans)
    for t in toBeRemoved:
      log.debug('Remove from queue: ', t.hash_transaction())
      self.transactions.remove(t)

  def solve_proof_of_work(self):
    """ solves the proof of work problem
    Starting with the random nonce, this thread will increment this
    value and hash the block with the nonce and test to see if the
    hash ends with the 'target' amount of zeros. If not, the nonce
    is incremented and a new hash is produced

    """
    log.info('Mining started...')
    self.client.broadcast_info('Mining started')
    self.isMining = True
    hash = SHA256.new()
    
    #self.b.computeMerkleRoot()
    for t in self.transactions:
      self.b.add_transaction(t)

    # create an array of target-length bytes
    target = bytes(self.b.target)
    hash.update(self.b.pack())
    digest = hash.digest()

    while not self.test_hash(digest, self.b.target):
      hash = SHA256.new()
      # update the nonce
      self.b.nonce += 1

      hash.update(self.b.pack())
      digest = hash.digest()
      if self.start_over:
        self.start_over = False
        return False
    return True
    
  def broadcast_info(self, info):
    """ subscribe to mining info 

    params:
      info -> the message to send to the subscriber callback
    """
    self.subscriber(info)
    
  def subscribe(self, subscriber):
    """ adds a subscriber to this Miner

    params:
      subscriber -> A callback function that will receive the info message
    """
    self.subscriber = subscriber
    
  def test_hash(self, hash, target):
    """ check if the last 'target' bits are zeros """
    int_hash = int(struct.unpack_from('I', hash[-4:])[0])
    low = (int_hash & -int_hash)
    lowBit = -1
    while (low):
      low >>= 1
      lowBit += 1
    if lowBit == target:
      log.info(bin(int_hash))
    return lowBit == target
    
  def verify_block_chain(self, debug=False):
    from db import DB
    d = DB()
    log.info('Verifying blockchain...')
    self.client.broadcast_info('Verifying blockchain')
    latest_block_hash = d.getLatestBlockHash()
    if not latest_block_hash:
      return True
    latest_block = d.getBlock(latest_block_hash)
    return latest_block.verify(debug=debug)
Beispiel #5
0
    if not latest_block_hash:
      return True
    latest_block = d.getBlock(latest_block_hash)
    return latest_block.verify(debug=debug)

if __name__ == '__main__':
  import sys, time
  from keystore import KeyStore
  from Crypto.PublicKey import RSA
  from Crypto import Random
  r = Random.new().read
  otherKey = RSA.generate(2048, r)
  myKey = RSA.generate(2048, r)
  from TransactionManager.coinbase import CoinBase
  m = Miner()
  c = CoinBase(owner=myKey)
  c.finish_transaction()

  t = Transaction(owner=myKey)

  t.add_output(Transaction.Output(20, myKey.publickey()))
  t.finish_transaction()
  
  
  b = Block()
  b.add_transaction(t)
  b.finish_block()
  
  t = Transaction(owner=myKey)

  t.add_output(Transaction.Output(25, myKey.publickey()))
Beispiel #6
0
        b.unpack(raw_block[0][0])
        return b

    def insertBlock(self, block):
        self.conn.execute(
            'insert into BLOCKS (ID, BLOCK) values (?, ?)',
            [block.hash_block(), block.pack()])
        self.conn.commit()


if __name__ == '__main__':
    from keystore import KeyStore
    from Crypto.PublicKey import RSA
    import time
    otherKey = RSA.generate(2048)
    db = DB()
    c = CoinBase()
    t = Transaction()
    #t.add_input(Transaction.Input(15, b'', 0))
    t.add_output(Transaction.Output(7, otherKey.publickey()))
    t.finish_transaction()
    #t = Transaction()
    #c = CoinBase()
    #t.add_input(Transaction.Input(17, b'', 0))
    #t.add_output(Transaction.Output(9, otherKey.publickey()))
    #t.finish_transaction()
    #print(db.getAllTransactions())
    #myOuts = db.getUnspentOutputs(KeyStore.getPublicKey())
    #print(myOuts)
    #print(db.getUnspentOutputs(otherKey.publickey()))
    time.sleep(10)
Beispiel #7
0
    @staticmethod
    def unpack(buf, offset=0):
      """ deserializes the output object """
      value = struct.unpack_from('I', buf, offset)[0]
      offset += 4
      n = struct.unpack_from('B', buf, offset)[0]
      offset += 1
      key = buf[offset:offset+450]
      pubKey = RSA.importKey(key)
      o = Transaction.Output(value, pubKey)
      o.n = n
      return o

if __name__ == '__main__':
  import sys, time
  from keystore import KeyStore
  from Crypto.PublicKey import RSA
  from Crypto import Random
  r = Random.new().read
  otherKey = RSA.generate(2048, r)
  myKey = RSA.generate(2048, r)
  from TransactionManager.coinbase import CoinBase
  c = CoinBase(owner=myKey)
  c.finish_transaction()
  #print('Verified: ', c.verify())
  t = Transaction(owner=myKey)

  t.add_output(Transaction.Output(20, myKey.publickey()))
  #t.input[0].owner = otherKey
  t.finish_transaction()
Beispiel #8
0
# cb.hash_transaction()
# print(cb.get_hash())

# i = Transaction.Input(1)
# i.pack(bytearray(), 0)

import sys, time
from keystore import KeyStore
from P2P.client_manager import *
from TransactionManager.transaction import *
from Crypto.PublicKey import RSA
otherKey = RSA.generate(2048)
from TransactionManager.coinbase import CoinBase

c = CoinBase()
#c.pack(withSig=True)

c.finish_transaction()

t = Transaction()

t.add_output(Transaction.Output(20, otherKey.publickey()))
t.finish_transaction()

#time.sleep(10)

# t = Transaction()

# t.add_output(Transaction.Output(12, otherKey.publickey()))
# t.finish_transaction()
Beispiel #9
0
class Miner:

    INVALID = -1

    def __init__(self):
        """ initializes the miner object """
        self.hashnum = SHA256.new()
        self.transactions = []
        self.start_over = False
        self.isMining = False

        self.client = P2PClientManager.getClient()
        self.client.subscribe(Message.NEW_BLOCK, self.handle_new_block)
        self.client.subscribe(Message.NEW_TRANSACTION,
                              self.handle_new_transaction)
        self.mining_thread = None

    def handle_new_transaction(self, trans):
        """ a callback function that is called when a new transaction is received
    from the p2p client

    params:
      trans -> the new transaction
    """
        if not isinstance(trans, Transaction):
            raise Exception('Not a Transaction object!')
        self.transactions.append(trans)
        log.debug('Received new transaction')
        if len(self.transactions) > 5 and not self.isMining:
            self.mining_thread = threading.Thread(target=self.solve_on_thread)
            self.mining_thread.start()

    def solve_on_thread(self):
        """ solves the POW and creates a new coinbase transaction when solved. """
        self.coinbase = CoinBase()
        self.transactions.append(self.coinbase)
        self.b = Block()
        result = self.solve_proof_of_work()
        if self.start_over:
            self.start_over = False
            log.debug('Mining stopped')
            self.isMining = False
            return
        if result:
            self.transactions = []
            log.info('Block solution found!, %d', self.b.nonce)
            self.client.broadcast_info('Block solution found')
            log.info('Block hash: %s',
                     self.b.hash_block(hex=True, withoutReward=False))
            self.broadcast_info('Block solution found!')
            if self.start_over:
                self.start_over = False
                self.isMining = False
                log.debug('Mining stopped')
                return

            self.coinbase.finish_transaction()
            self.b.finish_block()
            self.isMining = False

    def handle_new_block(self, block):
        """ a callback method that will be called when a new block is received
    from the p2p client.

    params:
      block -> the new block
    """
        log.debug('Received new block')
        self.start_over = True
        self.remove_queue_transactions(block)
        self.isMining = False

    def remove_queue_transactions(self, block):
        """ removes any transactions from the queue that were
    already included in the incoming block

    params:
      block -> the received block
    """
        toBeRemoved = []
        for t in block.transactionList:
            for trans in self.transactions:
                if t.hash_transaction() == trans.hash_transaction():
                    toBeRemoved.append(trans)
        for t in toBeRemoved:
            log.debug('Remove from queue: ', t.hash_transaction())
            self.transactions.remove(t)

    def solve_proof_of_work(self):
        """ solves the proof of work problem
    Starting with the random nonce, this thread will increment this
    value and hash the block with the nonce and test to see if the
    hash ends with the 'target' amount of zeros. If not, the nonce
    is incremented and a new hash is produced

    """
        log.info('Mining started...')
        self.client.broadcast_info('Mining started')
        self.isMining = True
        hash = SHA256.new()

        #self.b.computeMerkleRoot()
        for t in self.transactions:
            self.b.add_transaction(t)

        # create an array of target-length bytes
        target = bytes(self.b.target)
        hash.update(self.b.pack())
        digest = hash.digest()

        while not self.test_hash(digest, self.b.target):
            hash = SHA256.new()
            # update the nonce
            self.b.nonce += 1

            hash.update(self.b.pack())
            digest = hash.digest()
            if self.start_over:
                self.start_over = False
                return False
        return True

    def broadcast_info(self, info):
        """ subscribe to mining info 

    params:
      info -> the message to send to the subscriber callback
    """
        self.subscriber(info)

    def subscribe(self, subscriber):
        """ adds a subscriber to this Miner

    params:
      subscriber -> A callback function that will receive the info message
    """
        self.subscriber = subscriber

    def test_hash(self, hash, target):
        """ check if the last 'target' bits are zeros """
        int_hash = int(struct.unpack_from('I', hash[-4:])[0])
        low = (int_hash & -int_hash)
        lowBit = -1
        while (low):
            low >>= 1
            lowBit += 1
        if lowBit == target:
            log.info(bin(int_hash))
        return lowBit == target

    def verify_block_chain(self, debug=False):
        from db import DB
        d = DB()
        log.info('Verifying blockchain...')
        self.client.broadcast_info('Verifying blockchain')
        latest_block_hash = d.getLatestBlockHash()
        if not latest_block_hash:
            return True
        latest_block = d.getBlock(latest_block_hash)
        return latest_block.verify(debug=debug)