def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] address = request.args.get('address') bulletin_secret = request.args.get('bulletin_secret').replace(' ', "+") rid = TU.generate_rid(config, bulletin_secret) unspent_transactions = [ x for x in BU.get_wallet_unspent_transactions( config, mongo, address) ] regular_txns = [] txns_for_fastgraph = [] for txn in unspent_transactions: if 'signatures' in txn and txn['signatures']: fastgraph = FastGraph.from_dict(config, mongo, txn) origin_fasttrack = fastgraph.get_origin_relationship(rid) if origin_fasttrack: txns_for_fastgraph.append(txn) else: if 'rid' in txn and txn[ 'rid'] == rid and 'dh_public_key' in txn and txn[ 'dh_public_key']: txns_for_fastgraph.append(txn) else: regular_txns.append(txn) wallet = { 'balance': BU.get_wallet_balance(config, mongo, address), 'unspent_transactions': regular_txns, 'txns_for_fastgraph': txns_for_fastgraph } return json.dumps(wallet, indent=4)
def dispatch_request(self): address = request.args.get('address') wallet = { 'balance': BU.get_wallet_balance(address), 'unspent_transactions': [x for x in BU.get_wallet_unspent_transactions(address)] } return json.dumps(wallet, indent=4)
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] unspent = BU.get_wallet_unspent_transactions( config, mongo, request.json.get('address')) unspent_inputs = dict([(x['id'], x) for x in unspent]) input_sum = 0 for x in request.json.get('inputs'): found = False if x['id'] in unspent_inputs: for tx in unspent_inputs[x['id']].get('outputs'): input_sum += float(tx['value']) found = True break if not found: if mongo.db.blocks.find_one({'transactions.id': x['id']}, {'_id': 0}): return json.dumps({ 'status': 'error', 'msg': 'output already spent' }), 400 else: return json.dumps({ 'status': 'error', 'msg': 'transaction id not in blockchain' }), 400 output_sum = 0 for x in request.json.get('outputs'): output_sum += float(x['value']) if (output_sum + float(request.json.get('fee'))) > input_sum: return json.dumps({ 'status': 'error', 'msg': 'not enough inputs to pay for transaction outputs + fee' }) try: txn = TransactionFactory( config, mongo, public_key=request.json.get('public_key'), fee=float(request.json.get('fee')), inputs=[Input(x['id']) for x in request.json.get('inputs')], outputs=[ Output(x['to'], x['value']) for x in request.json.get('outputs') ]) except NotEnoughMoneyException as e: return json.dumps({ 'status': 'error', 'msg': 'not enough coins from referenced inputs to pay for transaction outputs + fee' }), 400 return '{"header": "%s", "hash": "%s"}' % (txn.header, txn.hash)
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] address = request.args.get('address') wallet = { 'balance': BU.get_wallet_balance(config, mongo, address), 'unspent_transactions': [ x for x in BU.get_wallet_unspent_transactions( config, mongo, address) ], } return json.dumps(wallet, indent=4)
def node(nonces=None, config=None): Config.from_dict(json.loads(config)) Peers.init() latest_block_index = Value('i', 0) my_peer = Config.peer_host + ":" + str(Config.peer_port) Config.max_duration = 300000 Config.block_version = 1 #p = Process(target=new_block_checker, args=(latest_block_index,)) status = Array('c', 'asldkjf') #p.start() Mongo.init() # default run state will be to mine some blocks! block = BU.get_latest_block() if block: latest_block_index.value = block.get('index') + 1 else: genesis_block = BlockFactory.get_genesis_block() genesis_block.save() Mongo.db.consensus.insert({ 'block': genesis_block.to_dict(), 'peer': 'me', 'id': genesis_block.signature, 'index': 0 }) block = BU.get_latest_block() latest_block_index.value = block.get('index') dup_test = Mongo.db.consensus.find({ 'peer': 'me', 'index': latest_block_index.value, 'block.version': BU.get_version_for_height(latest_block_index.value + 1) }).sort([('index', -1)]) if dup_test.count(): #print 'returning', latest_block_index.value + 1, BU.get_version_for_height(latest_block_index.value + 1) return transactions = Mongo.db.miner_transactions.find() transaction_objs = [] unspent_indexed = {} for txn in transactions: try: transaction = Transaction.from_dict(txn) transaction.verify() #check double spend address = str( P2PKHBitcoinAddress.from_pubkey( transaction.public_key.decode('hex'))) if address in unspent_indexed: unspent_ids = unspent_indexed[address] else: needed_value = sum( [float(x.value) for x in transaction.outputs]) + float(transaction.fee) res = BU.get_wallet_unspent_transactions( address, needed_value=needed_value) unspent_ids = [x['id'] for x in res] unspent_indexed[address] = unspent_ids failed1 = False failed2 = False used_ids_in_this_txn = [] for x in transaction.inputs: if x.id not in unspent_ids: failed1 = True if x.id in used_ids_in_this_txn: failed2 = True used_ids_in_this_txn.append(x.id) if failed1: Mongo.db.miner_transactions.remove( {'id': transaction.transaction_signature}) print 'transaction removed: input presumably spent already, not in unspent outputs', transaction.transaction_signature Mongo.db.failed_transactions.insert({ 'reason': 'input presumably spent already', 'txn': transaction.to_dict() }) elif failed2: Mongo.db.miner_transactions.remove( {'id': transaction.transaction_signature}) print 'transaction removed: using an input used by another transaction in this block', transaction.transaction_signature Mongo.db.failed_transactions.insert({ 'reason': 'using an input used by another transaction in this block', 'txn': transaction.to_dict() }) else: transaction_objs.append(transaction) except MissingInputTransactionException as e: #print 'missing this input transaction, will try again later' pass except InvalidTransactionSignatureException as e: print 'InvalidTransactionSignatureException: transaction removed' Mongo.db.miner_transactions.remove( {'id': transaction.transaction_signature}) Mongo.db.failed_transactions.insert({ 'reason': 'InvalidTransactionSignatureException', 'txn': transaction.to_dict() }) except InvalidTransactionException as e: print 'InvalidTransactionException: transaction removed' Mongo.db.miner_transactions.remove( {'id': transaction.transaction_signature}) Mongo.db.failed_transactions.insert({ 'reason': 'InvalidTransactionException', 'txn': transaction.to_dict() }) except Exception as e: #print e #print 'rejected transaction', txn['id'] pass except BaseException as e: #print e #print 'rejected transaction', txn['id'] pass try: block = BlockFactory.mine(transaction_objs, Config.public_key, Config.private_key, Config.max_duration, output, latest_block_index, status, nonces) except Exception as e: raise if block: dup_test = Mongo.db.consensus.find_one({ 'peer': 'me', 'index': block.index, 'block.version': BU.get_version_for_height(block.index) }) if not dup_test: print '\r\nCandidate submitted for index:', block.index print '\r\nTransactions:' for x in block.transactions: print x.transaction_signature Mongo.db.consensus.insert({ 'peer': 'me', 'index': block.index, 'id': block.signature, 'block': block.to_dict() }) print '\r\nSent block to:' for peer in Peers.peers: try: block_dict = block.to_dict() block_dict['peer'] = my_peer requests.post('http://{peer}/newblock'.format( peer=peer.host + ":" + str(peer.port)), json=block_dict, timeout=3, headers={'Connection': 'close'}) print peer.host + ":" + str(peer.port) except Exception as e: print e try: print 'reporting bad peer' requests.post('https://yadacoin.io/peers', json={ 'host': peer.host, 'port': str(peer.port), 'failed': True }, timeout=3, headers={'Connection': 'close'}) except: print 'failed to report bad peer' pass
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] res = mongo.db.signed_transactions.find_one( {'hash': request.json.get('hash')}) if res: return 'no', 400 try: rid = TU.generate_rid(config, request.json.get('bulletin_secret')) my_entry_for_relationship = BU.get_transaction_by_rid( config, mongo, rid, config.wif, rid=True, my=True, public_key=config.public_key) their_entry_for_relationship = BU.get_transaction_by_rid( config, mongo, rid, rid=True, raw=True, theirs=True, public_key=config.public_key) verified = verify_signature( base64.b64decode(request.json.get('bulletin_secret')), my_entry_for_relationship['relationship']['their_username'], their_entry_for_relationship['public_key'].decode('hex')) if not verified: return 'no', 400 verified = verify_signature( base64.b64decode(request.json.get('id')), request.json.get('hash'), their_entry_for_relationship['public_key'].decode('hex')) address = str( P2PKHBitcoinAddress.from_pubkey( their_entry_for_relationship['public_key'].decode('hex'))) found = False for x in BU.get_wallet_unspent_transactions( config, mongo, address, [request.json.get('input')]): if request.json.get('input') == x['id']: found = True if found: res = mongo.db.signed_transactions.find( {'input': request.json.get('input')}) if res.count(): return 'already signed this input', 400 else: return 'no transactions with this input found', 400 if verified: transaction_signature = TU.generate_signature_with_private_key( config.private_key, request.json.get('hash')) signature = { 'signature': transaction_signature, 'hash': request.json.get('hash'), 'bulletin_secret': request.json.get('bulletin_secret'), 'input': request.json.get('input'), 'id': request.json.get('id') } mongo.db.signed_transactions.insert(signature) if '_id' in signature: del signature['_id'] return json.dumps(signature) else: return 'no', 400 except Exception as e: return json.dumps({'status': 'error', 'msg': e}), 400
config = Config(json.loads(f.read())) else: print 'no config file found at \'%s\'' % args.config exit() mongo = Mongo(config) consensus = Consensus(config, mongo, True) consensus.sync_bottom_up() keys = get_keys() generate_some_blocks(keys) pprint.pprint(keys) # Assemble the list of inputs inputs = [] for key in keys: input_txns = BU.get_wallet_unspent_transactions(config, mongo, key.get('address')) for tx in input_txns: for i, out in enumerate(tx['outputs']): if out['to'] != key.get('address'): continue inputs.append({ "hash": tx['hash'], "id": tx['id'], "index": i, "value": out['value'], "time": tx['time'], "height": tx['height'], "fee": tx['fee'], "public_key": tx['public_key'], "signature": TU.generate_signature(tx['id'], key['private_key']), "address": key.get('address')
def create_relationship(): # demo site if request.method == 'GET': bulletin_secret = request.args.get('bulletin_secret', '') username = request.args.get('username', '') to = request.args.get('to', '') else: bulletin_secret = request.json.get('bulletin_secret', '') username = request.json.get('username', '') to = request.json.get('to', '') if not bulletin_secret: return 'error: "bulletin_secret" missing', 400 if not username: return 'error: "username" missing', 400 if not to: return 'error: "to" missing', 400 rid = TU.generate_rid(bulletin_secret) dup = Mongo.db.blocks.find({'transactions.rid': rid}) if dup.count(): for txn in dup: if txn['public_key'] == Config.public_key: return json.dumps({ "success": False, "status": "Already added" }) input_txns = BU.get_wallet_unspent_transactions(Config.address) miner_transactions = Mongo.db.miner_transactions.find() mtxn_ids = [] for mtxn in miner_transactions: for mtxninput in mtxn['inputs']: mtxn_ids.append(mtxninput['id']) checked_out_txn_ids = Mongo.db.checked_out_txn_ids.find() for mtxn in checked_out_txn_ids: mtxn_ids.append(mtxn['id']) a = os.urandom(32) dh_public_key = scalarmult_base(a).encode('hex') dh_private_key = a.encode('hex') transaction = TransactionFactory(bulletin_secret=bulletin_secret, username=username, fee=0.01, public_key=Config.public_key, dh_public_key=dh_public_key, private_key=Config.private_key, dh_private_key=dh_private_key, outputs=[Output(to=to, value=1)]) TU.save(transaction.transaction) Mongo.db.miner_transactions.insert(transaction.transaction.to_dict()) job = Process(target=endpoints.TxnBroadcaster.txn_broadcast_job, args=(transaction.transaction, )) job.start() my_bulletin_secret = Config.get_bulletin_secret() bulletin_secrets = sorted([str(my_bulletin_secret), str(bulletin_secret)], key=str.lower) rid = hashlib.sha256(str(bulletin_secrets[0]) + str(bulletin_secrets[1])).digest().encode('hex') Mongo.site_db.friends.insert({ 'rid': rid, 'relationship': { 'bulletin_secret': bulletin_secret } }) return json.dumps({"success": True})