Esempio n. 1
0
 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)
Esempio n. 2
0
 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)
Esempio n. 3
0
    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)
Esempio n. 4
0
 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)
Esempio n. 5
0
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
Esempio n. 6
0
    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
Esempio n. 7
0
            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')
Esempio n. 8
0
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})