def get_transaction_by_rid(cls, selector, rid=False, raw=False):
        from block import Block
        from transaction import Transaction
        from crypt import Crypt
        ds = Config.get_bulletin_secret()
        if not rid:
            selectors = [TU.hash(ds + selector), TU.hash(selector + ds)]
        else:
            if not isinstance(selector, list):
                selectors = [
                    selector,
                ]

        for block in Mongo.db.blocks.find(
            {"transactions": {
                "$elemMatch": {
                    "relationship": {
                        "$ne": ""
                    }
                }
            }}):
            for transaction in block.get('transactions'):
                if transaction.get('rid') in selectors:
                    if 'relationship' in transaction:
                        if not raw:
                            try:
                                cipher = Crypt(Config.wif)
                                decrypted = cipher.decrypt(
                                    transaction['relationship'])
                                relationship = json.loads(decrypted)
                                transaction['relationship'] = relationship
                            except:
                                continue
                    return transaction
Example #2
0
    def run(cls, config, mongo, to, value):
        Peers.init(config, mongo, config.network)

        try:
            transaction = TransactionFactory(
                config,
                mongo,
                fee=0.01,
                public_key=config.public_key,
                private_key=config.private_key,
                outputs=[Output(to=to, value=value)])
        except NotEnoughMoneyException as e:
            print "not enough money yet"
            return
        except:
            raise
        try:
            transaction.transaction.verify()
        except:
            print 'transaction failed'
        TU.save(transaction.transaction)
        print 'Transaction generated successfully. Sending:', value, 'To:', to
        for peer in Peers.peers:
            try:
                socketIO = SocketIO(peer.host,
                                    peer.port,
                                    wait_for_connection=False)
                chat_namespace = socketIO.define(ChatNamespace, '/chat')
                chat_namespace.emit('newtransaction',
                                    transaction.transaction.to_dict())
                socketIO.disconnect()
                print 'Sent to:', peer.host, peer.port
            except Exception as e:
                print e
Example #3
0
    def run(cls, config, mongo):
        used_inputs = []
        new_inputs = []
        for x in mongo.site_db.faucet.find({'active': True}):
            balance = BU.get_wallet_balance(config, mongo, x['address'])
            if balance >= 25:
                mongo.site_db.faucet.update({'_id': x['_id']}, {
                    'active': False,
                    'address': x['address']
                })

                continue
            last_id_in_blockchain = x.get('last_id')
            if last_id_in_blockchain and not mongo.db.blocks.find({
                    'transactions.id':
                    last_id_in_blockchain
            }).count():

                continue

            try:
                transaction = TransactionFactory(
                    config,
                    mongo,
                    block_height=BU.get_latest_block(config, mongo)['index'],
                    fee=0.01,
                    public_key=config.public_key,
                    private_key=config.private_key,
                    outputs=[Output(to=x['address'], value=5)])
            except NotEnoughMoneyException as e:
                print "not enough money yet"
                return
            except Exception as e:
                print x
            try:
                transaction.transaction.verify()
            except:
                mongo.site_db.failed_faucet_transactions.insert(
                    transaction.transaction.to_dict())
                print 'faucet transaction failed'
            TU.save(config, mongo, transaction.transaction)
            x['last_id'] = transaction.transaction.transaction_signature
            mongo.site_db.faucet.update({'_id': x['_id']}, x)
            print 'saved. sending...', x['address']
            for peer in Peers.peers:
                try:
                    socketIO = SocketIO(peer.host,
                                        peer.port,
                                        wait_for_connection=False)
                    chat_namespace = socketIO.define(ChatNamespace, '/chat')
                    chat_namespace.emit('newtransaction',
                                        transaction.transaction.to_dict())
                    socketIO.disconnect()
                except Exception as e:
                    print e
Example #4
0
    def from_dict(cls, config):
        from transactionutils import TU
        cls.seed = config.get('seed', '')
        cls.xprv = config.get('xprv', '')
        cls.username = config.get('username', '')
        cls.network = config.get('network', 'mainnet')
        cls.public_key = config['public_key']
        cls.address = str(P2PKHBitcoinAddress.from_pubkey(cls.public_key.decode('hex')))

        cls.private_key = config['private_key']
        cls.wif = cls.generate_wif(cls.private_key)
        cls.bulletin_secret = TU.generate_deterministic_signature(config, config['username'], config['private_key'])

        cls.mongodb_host = config['mongodb_host']
        cls.database = config['database']
        cls.site_database = config['site_database']
        cls.web_server_host = config['web_server_host']
        cls.web_server_port = config['web_server_port']
        if config['peer_host'] == '0.0.0.0' or config['peer_host'] == 'localhost':
            raise Exception("cannot use localhost or 0.0.0.0, must specify public ipv4 address")
        if config['peer_host'] == '[my public ip]':
            raise Exception("please configure your peer_post to your public ipv4 address")
        cls.peer_host = config['peer_host']
        cls.peer_port = config['peer_port']
        cls.serve_host = config['serve_host']
        cls.serve_port = config['serve_port']
        cls.callbackurl = config['callbackurl']
        cls.fcm_key = config['fcm_key']
Example #5
0
    def run(cls, config, mongo, to, value):
        Peers.init(config, mongo, config.network)

        try:
            transaction = TransactionFactory(config,
                                             mongo,
                                             block_height=BU.get_latest_block(
                                                 config, mongo)['index'],
                                             fee=0.01,
                                             public_key=config.public_key,
                                             private_key=config.private_key,
                                             outputs=[{
                                                 'to': to,
                                                 'value': value
                                             }])
        except NotEnoughMoneyException as e:
            print "not enough money yet"
            return
        except:
            raise
        try:
            transaction.transaction.verify()
        except:
            print 'transaction failed'
        TU.save(config, mongo, transaction.transaction)
        print 'Transaction generated successfully. Sending:', value, 'To:', to
        for peer in Peers.peers:
            try:
                with SocketIO(peer.host,
                              peer.port,
                              ChatNamespace,
                              wait_for_connection=False) as socketIO:
                    chat_namespace = socketIO.define(ChatNamespace, '/chat')
                    chat_namespace.emit('newtransaction',
                                        transaction.transaction.to_dict())
                    socketIO.disconnect()
                    print 'Sent to:', peer.host, peer.port
            except Exception as e:
                print e
 def verify_message(cls, rid, message):
     from crypt import Crypt
     sent = False
     received = False
     txns = cls.get_transactions_by_rid(rid, rid=True, raw=True)
     shared_secrets = TU.get_shared_secrets_by_rid(rid)
     for txn in txns:
         for shared_secret in list(set(shared_secrets)):
             try:
                 cipher = Crypt(shared_secret.encode('hex'), shared=True)
                 decrypted = cipher.shared_decrypt(txn['relationship'])
                 signin = json.loads(decrypted)
                 if u'signIn' in signin and message == signin['signIn']:
                     if Config.public_key != txn['public_key']:
                         received = True
                     else:
                         sent = True
             except:
                 pass
     return sent, received
Example #7
0
 def get_bulletin_secret(cls):
     from transactionutils import TU
     return TU.generate_deterministic_signature(Config.username)
Example #8
0
 def get_bulletin_secret(self):
     from transactionutils import TU
     return TU.generate_deterministic_signature(self, self.username, self.private_key)
Example #9
0
 def generate_transaction_signature(self):
     return TU.generate_signature(self.hash, self.private_key)
Example #10
0
    def __init__(self,
                 config,
                 mongo,
                 block_height,
                 bulletin_secret='',
                 username='',
                 value=0,
                 fee=0.0,
                 requester_rid='',
                 requested_rid='',
                 public_key='',
                 dh_public_key='',
                 private_key='',
                 dh_private_key='',
                 to='',
                 inputs='',
                 outputs='',
                 coinbase=False,
                 chattext=None,
                 signin=None):
        self.config = config
        self.mongo = mongo
        self.block_height = block_height
        self.bulletin_secret = bulletin_secret
        self.username = username
        self.requester_rid = requester_rid
        self.requested_rid = requested_rid
        self.public_key = public_key
        self.dh_public_key = dh_public_key
        self.private_key = private_key
        self.value = value
        self.fee = float(fee)
        self.dh_private_key = dh_private_key
        self.to = to
        self.time = str(int(time.time()))
        self.outputs = []
        for x in outputs:
            self.outputs.append(Output.from_dict(x))
        self.inputs = []
        for x in inputs:
            if 'signature' in x:
                self.inputs.append(
                    ExternalInput.from_dict(self.config, self.mongo, x))
            else:
                self.inputs.append(Input.from_dict(x))
        self.coinbase = coinbase
        self.chattext = chattext
        self.signin = signin
        self.do_money()
        inputs_concat = self.get_input_hashes()
        outputs_concat = self.get_output_hashes()
        if bulletin_secret:
            self.rid = self.generate_rid()
            if self.chattext:
                self.relationship = json.dumps({"chatText": self.chattext})
                self.cipher = Crypt(self.config.wif)
                self.encrypted_relationship = self.cipher.encrypt(
                    self.relationship)
            elif self.signin:
                for shared_secret in TU.get_shared_secrets_by_rid(
                        self.config, self.mongo, self.rid):
                    self.relationship = SignIn(self.signin)
                    self.cipher = Crypt(shared_secret.encode('hex'),
                                        shared=True)
                    self.encrypted_relationship = self.cipher.shared_encrypt(
                        self.relationship.to_json())
            else:
                if not self.dh_public_key or not self.dh_private_key:
                    a = os.urandom(32)
                    self.dh_public_key = scalarmult_base(a).encode('hex')
                    self.dh_private_key = a.encode('hex')
                self.relationship = self.generate_relationship()
                if not private_key:
                    raise BaseException('missing private key')
                self.cipher = Crypt(self.config.wif)
                self.encrypted_relationship = self.cipher.encrypt(
                    self.relationship.to_json())
        else:
            self.rid = ''
            self.encrypted_relationship = ''

        self.header = (self.public_key + self.time + self.dh_public_key +
                       self.rid + self.encrypted_relationship +
                       "{0:.8f}".format(self.fee) + self.requester_rid +
                       self.requested_rid + inputs_concat + outputs_concat)
        self.hash = hashlib.sha256(self.header).digest().encode('hex')
        if self.private_key:
            self.transaction_signature = TU.generate_signature_with_private_key(
                private_key, self.hash)
        else:
            self.transaction_signature = ''
        self.transaction = self.generate_transaction()
    def get_transactions_by_rid(cls,
                                selector,
                                rid=False,
                                raw=False,
                                returnheight=True,
                                bulletin_secret=None):
        #selectors is old code before we got an RID by sorting the bulletin secrets
        from block import Block
        from transaction import Transaction
        from crypt import Crypt
        ds = Config.get_bulletin_secret()

        if not rid:
            selectors = [TU.hash(ds + selector), TU.hash(selector + ds)]
        else:
            if not isinstance(selector, list):
                selectors = [
                    selector,
                ]
            else:
                selectors = selector

        transactions_by_rid_cache = Mongo.db.transactions_by_rid_cache.find({
            'raw':
            raw,
            'rid':
            rid,
            'bulletin_secret':
            bulletin_secret,
            'returnheight':
            returnheight,
            'selector': {
                '$in': selectors
            }
        }).sort([('height', -1)])
        latest_block = cls.get_latest_block()
        if transactions_by_rid_cache.count():
            transactions_by_rid_cache = transactions_by_rid_cache[0]
            block_height = transactions_by_rid_cache['height']
        else:
            block_height = 0
        transactions = []
        blocks = Mongo.db.blocks.find({
            "transactions.rid": {
                "$in": selectors
            },
            "transactions": {
                "$elemMatch": {
                    "relationship": {
                        "$ne": ""
                    }
                }
            },
            'index': {
                '$gt': block_height
            }
        })
        for block in blocks:
            for transaction in block.get('transactions'):
                if 'relationship' in transaction and transaction[
                        'relationship']:
                    if returnheight:
                        transaction['height'] = block['index']
                    if not raw:
                        try:
                            cipher = Crypt(Config.wif)
                            decrypted = cipher.decrypt(
                                transaction['relationship'])
                            relationship = json.loads(decrypted)
                            transaction['relationship'] = relationship
                        except:
                            continue
                    for selector in selectors:
                        print 'caching transactions_by_rid at height:', block[
                            'index']
                        Mongo.db.transactions_by_rid_cache.insert({
                            'raw':
                            raw,
                            'rid':
                            rid,
                            'bulletin_secret':
                            bulletin_secret,
                            'returnheight':
                            returnheight,
                            'selector':
                            selector,
                            'txn':
                            transaction,
                            'height':
                            block['index']
                        })
                    transactions.append(transaction)
        if not transactions:
            for selector in selectors:
                Mongo.db.transactions_by_rid_cache.insert({
                    'raw':
                    raw,
                    'rid':
                    rid,
                    'bulletin_secret':
                    bulletin_secret,
                    'returnheight':
                    returnheight,
                    'selector':
                    selector,
                    'height':
                    latest_block['index']
                })
        for x in Mongo.db.transactions_by_rid_cache.find({
                'raw': raw,
                'rid': rid,
                'returnheight': returnheight,
                'selector': {
                    '$in': selectors
                }
        }):
            if 'txn' in x:
                yield x['txn']
Example #12
0
    def do_payout_for_block(self, block):
        # check if we already paid out

        already_used = self.already_used(block.get_coinbase())
        if already_used:
            self.mongo.db.shares.remove({'index': block.index})
            return

        existing = self.mongo.db.share_payout.find_one({'index': block.index})
        if existing:
            pending = self.mongo.db.miner_transactions.find_one(
                {'inputs.id': block.get_coinbase().transaction_signature})
            if pending:
                return
            else:
                # rebroadcast
                transaction = Transaction.from_dict(
                    self.config, self.mongo,
                    BU.get_latest_block(self.config, self.mongo)['index'],
                    existing['txn'])
                TU.save(self.config, self.mongo, transaction)
                self.broadcast_transaction(transaction)
                return

        try:
            shares = self.get_share_list_for_height(block.index)
        except Exception as e:
            print e
            return

        total_reward = block.get_coinbase()
        if total_reward.outputs[0].to != self.config.address:
            return
        pool_take = 0.01
        total_pool_take = total_reward.outputs[0].value * pool_take
        total_payout = total_reward.outputs[0].value - total_pool_take

        outputs = []
        for address, x in shares.iteritems():
            exists = self.mongo.db.share_payout.find_one({
                'index':
                block.index,
                'txn.outputs.to':
                address
            })
            if exists:
                raise PartialPayoutException(
                    'this index has been partially paid out.')

            payout = total_payout * x['payout_share']
            outputs.append({'to': address, 'value': payout})

        try:
            transaction = TransactionFactory(
                self.config,
                self.mongo,
                block_height=block.index,
                fee=0.0001,
                public_key=self.config.public_key,
                private_key=self.config.private_key,
                inputs=[{
                    'id': total_reward.transaction_signature
                }],
                outputs=outputs)
        except NotEnoughMoneyException as e:
            print "not enough money yet"
            return
        except Exception as e:
            print e

        try:
            transaction.transaction.verify()
        except:
            raise
            print 'faucet transaction failed'

        TU.save(self.config, self.mongo, transaction.transaction)
        self.mongo.db.share_payout.insert({
            'index':
            block.index,
            'txn':
            transaction.transaction.to_dict()
        })

        self.broadcast_transaction(transaction.transaction)
Example #13
0
    def __init__(self, config, mongo, bulletin_secret, ids, wallet=None):
        self.config = config
        self.mongo = mongo
        self.friend_requests = []
        self.sent_friend_requests = []
        self.friends = []
        self.posts = []
        self.logins = []
        self.messages = []
        self.new_messages = []
        self.reacts = []
        self.comments = []
        self.comment_reacts = []
        self.already_added_messages = []
        self.bulletin_secret = str(bulletin_secret)
        self.ids = ids

        all_relationships = [x for x in BU.get_all_usernames(config, mongo)]
        self.rid_usernames = dict([(x['rid'],
                                    x['relationship']['their_username'])
                                   for x in all_relationships])
        if wallet:  # disabling for now
            self.wallet_mode = True

            rids = [x['rid'] for x in all_relationships]
            self.rid_transactions = BU.get_transactions_by_rid(
                self.config,
                self.mongo,
                rids,
                bulletin_secret=wallet.bulletin_secret,
                rid=True,
                raw=True,
                returnheight=True)
        else:
            self.wallet_mode = False
            self.registered = False
            self.pending_registration = False
            bulletin_secrets = sorted(
                [str(config.bulletin_secret),
                 str(bulletin_secret)],
                key=str.lower)
            rid = hashlib.sha256(
                str(bulletin_secrets[0]) +
                str(bulletin_secrets[1])).digest().encode('hex')
            self.rid = rid

            res = self.mongo.site_db.usernames.find({"rid": self.rid})
            if res.count():
                self.human_hash = res[0]['username']
            else:
                self.human_hash = humanhash.humanize(self.rid)
            start_height = 0
            # this will get any transactions between the client and server
            nodes = BU.get_transactions_by_rid(self.config,
                                               self.mongo,
                                               bulletin_secret,
                                               config.bulletin_secret,
                                               raw=True,
                                               returnheight=True)
            already_done = []
            for node in nodes:
                if node.get('dh_public_key'):
                    test = {
                        'rid': node.get('rid'),
                        'requester_rid': node.get('requester_id'),
                        'requested_rid': node.get('requested_id'),
                        'id': node.get('id')
                    }
                    node['username'] = '******'
                    if test in already_done:
                        continue
                    else:
                        self.friends.append(node)
                        already_done.append(test)

            self.registered = False
            shared_secrets = TU.get_shared_secrets_by_rid(config, mongo, rid)
            if shared_secrets:
                self.registered = True

            if self.registered:
                for x in self.friends:
                    for y in x['outputs']:
                        if y['to'] != config.address:
                            self.mongo.site_db.usernames.update(
                                {
                                    'rid': self.rid,
                                    'username': self.human_hash,
                                }, {
                                    'rid': self.rid,
                                    'username': self.human_hash,
                                    'to': y['to'],
                                    'relationship': {
                                        'bulletin_secret': bulletin_secret
                                    }
                                },
                                upsert=True)
            else:
                # not regisered, let's check for a pending transaction
                res = self.mongo.db.miner_transactions.find({
                    'rid': self.rid,
                    'public_key': {
                        '$ne': self.config.public_key
                    }
                })
                res2 = self.mongo.db.miner_transactions.find({
                    'rid':
                    self.rid,
                    'public_key':
                    self.config.public_key
                })

                if res.count() and res2.count():
                    self.pending_registration = True
    def __init__(self,
                 bulletin_secret='',
                 username='',
                 value=0,
                 fee=0.0,
                 requester_rid='',
                 requested_rid='',
                 public_key='',
                 dh_public_key='',
                 private_key='',
                 dh_private_key='',
                 to='',
                 inputs='',
                 outputs='',
                 coinbase=False,
                 chattext=None,
                 signin=None):
        self.bulletin_secret = bulletin_secret
        self.username = username
        self.requester_rid = requester_rid
        self.requested_rid = requested_rid
        self.public_key = public_key
        self.dh_public_key = dh_public_key
        self.private_key = private_key
        self.value = value
        self.fee = float(fee)
        self.dh_private_key = dh_private_key
        self.to = to
        self.outputs = outputs or []
        self.inputs = inputs
        self.coinbase = coinbase
        self.chattext = chattext
        self.signin = signin
        self.do_money()
        inputs_concat = self.get_input_hashes()
        outputs_concat = self.get_output_hashes()
        if bulletin_secret:
            self.rid = self.generate_rid()
            if self.chattext:
                self.relationship = json.dumps({"chatText": self.chattext})
            elif self.signin:
                for shared_secret in TU.get_shared_secrets_by_rid(self.rid):
                    self.relationship = SignIn(self.signin)
                    self.cipher = Crypt(shared_secret.encode('hex'),
                                        shared=True)
                    self.encrypted_relationship = self.cipher.shared_encrypt(
                        self.relationship.to_json())
            else:
                self.relationship = self.generate_relationship()
                if not private_key:
                    raise BaseException('missing private key')
                self.cipher = Crypt(Config.wif)
                self.encrypted_relationship = self.cipher.encrypt(
                    self.relationship.to_json())
        else:
            self.rid = ''
            self.encrypted_relationship = ''
        self.hash = hashlib.sha256(self.dh_public_key + self.rid +
                                   self.encrypted_relationship +
                                   "{0:.8f}".format(self.fee) +
                                   self.requester_rid + self.requested_rid +
                                   inputs_concat +
                                   outputs_concat).digest().encode('hex')

        self.transaction_signature = self.generate_transaction_signature()
        self.transaction = self.generate_transaction()
 def generate_transaction_signature(self):
     return TU.generate_signature(self.hash)
Example #16
0
 def get_bulletin_secret(cls, private_key=None):
     from transactionutils import TU
     return TU.generate_deterministic_signature(config.username,
                                                private_key)