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
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
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
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']
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
def get_bulletin_secret(cls): from transactionutils import TU return TU.generate_deterministic_signature(Config.username)
def get_bulletin_secret(self): from transactionutils import TU return TU.generate_deterministic_signature(self, self.username, self.private_key)
def generate_transaction_signature(self): return TU.generate_signature(self.hash, self.private_key)
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']
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)
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)
def get_bulletin_secret(cls, private_key=None): from transactionutils import TU return TU.generate_deterministic_signature(config.username, private_key)