예제 #1
0
파일: builder.py 프로젝트: kmn/bc4py
 def get_balance(self, confirm=6):
     assert confirm < builder.cashe_limit - builder.batch_size, 'Too few cashe size.'
     assert builder.best_block, 'Not DataBase init.'
     # DataBase
     balance = self.db_balance.copy()
     with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
         cur = db.cursor()
         # Memory
         limit_height = builder.best_block.height - confirm
         for block in builder.best_chain:
             for tx in block.txs:
                 move_log = read_txhash2log(tx.hash, cur)
                 if move_log is None:
                     if tx.hash in self.memory_movement:
                         move_log = self.memory_movement[tx.hash]
                 if move_log:
                     for user, coins in move_log.movement.items():
                         for coin_id, amount in coins:
                             if limit_height < block.height:
                                 if amount < 0:
                                     balance.add_coins(user, coin_id, amount)
                             else:
                                 balance.add_coins(user, coin_id, amount)
         # Unconfirmed
         for tx in list(tx_builder.unconfirmed.values()):
             move_log = read_txhash2log(tx.hash, cur)
             if move_log is None:
                 if tx.hash in self.memory_movement:
                     move_log = self.memory_movement[tx.hash]
             if move_log:
                 for user, coins in move_log.movement.items():
                     for coin_id, amount in coins:
                         if amount < 0:
                             balance.add_coins(user, coin_id, amount)
     return balance
예제 #2
0
async def contract_transfer(request):
    start = time()
    post = await web_base.content_type_json_check(request)
    try:
        c_address = post['c_address']
        c_method = post['c_method']
        c_args = post['c_args']
        send_pairs = post.get('send_pairs', None)
        sender_name = post.get('from', C.ANT_NAME_UNKNOWN)
        with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
            cur = db.cursor()
            sender = read_name2user(sender_name, cur)
            tx = create_contract_transfer_tx(c_address=c_address,
                                             cur=cur,
                                             c_method=c_method,
                                             c_args=c_args,
                                             send_pairs=send_pairs,
                                             sender=sender)
            if not send_newtx(new_tx=tx, outer_cur=cur):
                raise Exception('Failed to send new tx.')
            db.commit()
        return web_base.json_res({
            'hash': hexlify(tx.hash).decode(),
            'gas_amount': tx.gas_amount,
            'gas_price': tx.gas_price,
            'fee': tx.gas_amount * tx.gas_price,
            'time': round(time() - start, 3)
        })
    except Exception:
        return web_base.error_res()
예제 #3
0
파일: createtx.py 프로젝트: yoosofan/bc4py
async def change_mint_tx(request):
    post = await web_base.content_type_json_check(request)
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        try:
            user_name = post.get('account', C.ANT_NAME_UNKNOWN)
            sender = read_name2user(user_name, cur)
            mint, mintcoin_tx = change_mintcoin(
                mint_id=int(post['mint_id']),
                cur=cur,
                amount=int(post.get('amount', 0)),
                message=post.get('message', None),
                image=post.get('image', None),
                additional_issue=bool(post['additional_issue'])
                if 'additional_issue' in post else None,
                sender=sender)
            if not send_newtx(new_tx=mintcoin_tx, outer_cur=cur):
                raise BaseException('Failed to send new tx.')
            db.commit()
            data = mintcoin_tx.getinfo()
            return web_base.json_res({
                'txhash': data['hash'],
                'mintcoin': mint.getinfo()
            })
        except BaseException:
            return web_base.error_res()
예제 #4
0
async def validate_unconfirmed(request):
    start = time()
    post = await web_base.content_type_json_check(request)
    try:
        txhash = unhexlify(post['hash'].encode())
        tx = tx_builder.get_tx(txhash=txhash)
        if tx is None or tx.height is not None:
            return web_base.error_res('You cannot validate tx. {}'.format(tx))
        with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
            cur = db.cursor()
            new_tx = create_signed_tx_as_validator(tx=tx)
            assert tx is not new_tx, 'tx={}, new_tx={}'.format(
                id(tx), id(new_tx))
            if not send_newtx(new_tx=new_tx, outer_cur=cur):
                raise Exception('Failed to send new tx.')
            db.commit()
            return web_base.json_res({
                'hash': hexlify(new_tx.hash).decode(),
                'gas_amount': new_tx.gas_amount,
                'gas_price': new_tx.gas_price,
                'fee': new_tx.gas_amount * new_tx.gas_price,
                'time': round(time() - start, 3)
            })
    except Exception:
        return web_base.error_res()
예제 #5
0
async def issue_mint_tx(request):
    start = time()
    post = await web_base.content_type_json_check(request)
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        try:
            user_name = post.get('from', C.ANT_NAME_UNKNOWN)
            sender = read_name2user(user_name, cur)
            mint_id, tx = issue_mintcoin(
                name=post['name'],
                unit=post['unit'],
                digit=post.get('digit', 8),
                amount=post['amount'],
                cur=cur,
                description=post.get('description', None),
                image=post.get('image', None),
                additional_issue=post.get('additional_issue', True),
                sender=sender)
            if not send_newtx(new_tx=tx, outer_cur=cur):
                raise BaseException('Failed to send new tx.')
            db.commit()
            return web_base.json_res({
                'hash': hexlify(tx.hash).decode(),
                'gas_amount': tx.gas_amount,
                'gas_price': tx.gas_price,
                'fee': tx.gas_amount * tx.gas_price,
                'time': round(time() - start, 3),
                'mint_id': mint_id
            })
        except BaseException:
            return web_base.error_res()
예제 #6
0
async def change_mint_tx(request):
    start = time()
    post = await web_base.content_type_json_check(request)
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        try:
            user_name = post.get('from', C.ANT_NAME_UNKNOWN)
            sender = read_name2user(user_name, cur)
            tx = change_mintcoin(mint_id=post['mint_id'],
                                 cur=cur,
                                 amount=post.get('amount'),
                                 description=post.get('description'),
                                 image=post.get('image'),
                                 setting=post.get('setting'),
                                 new_address=post.get('new_address'),
                                 sender=sender)
            if not send_newtx(new_tx=tx, outer_cur=cur):
                raise BaseException('Failed to send new tx.')
            db.commit()
            return web_base.json_res({
                'hash': hexlify(tx.hash).decode(),
                'gas_amount': tx.gas_amount,
                'gas_price': tx.gas_price,
                'fee': tx.gas_amount * tx.gas_price,
                'time': round(time() - start, 3)
            })
        except BaseException:
            return web_base.error_res()
예제 #7
0
파일: createtx.py 프로젝트: yoosofan/bc4py
async def send_many_user(request):
    start = time.time()
    if P.F_NOW_BOOTING:
        return web.Response(text='Now booting...', status=403)
    post = await web_base.content_type_json_check(request)
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        try:
            user_name = post.get('from', C.ANT_NAME_UNKNOWN)
            user_id = read_name2user(user_name, cur)
            send_pairs = list()
            for address, coin_id, amount in post['pairs']:
                send_pairs.append((address, int(coin_id), int(amount)))
            message = post.get('message', None)
            if message:
                msg_type = C.MSG_PLAIN
                msg_body = message.encode()
            else:
                msg_type = C.MSG_NONE
                msg_body = b''
            new_tx = send_many(user_id,
                               send_pairs,
                               cur,
                               msg_type=msg_type,
                               msg_body=msg_body)
            if not send_newtx(new_tx=new_tx, outer_cur=cur):
                raise BaseException('Failed to send new tx.')
            db.commit()
            return web_base.json_res({
                'txhash': hexlify(new_tx.hash).decode(),
                'time': round(time.time() - start, 3)
            })
        except Exception as e:
            db.rollback()
            return web_base.error_res()
예제 #8
0
async def contract_create(request):
    post = await web_base.content_type_json_check(request)
    with closing(create_db(V.DB_ACCOUNT_PATH, f_on_memory=True)) as db:
        cur = db.cursor()
        try:
            # バイナリをピックルしオブジェクトに戻す
            c_bin = unhexlify(post['hex'].encode())
            c_cs = {
                k.encode(errors='ignore'): v.encode(errors='ignore')
                for k, v in post.get('c_cs', dict()).items()
            }
            binary2contract(c_bin)  # can compile?
            sender_name = post.get('account', C.ANT_NAME_UNKNOWN)
            sender_id = read_name2user(sender_name, cur)
            c_address, c_tx = create_contract_tx(c_bin, cur, sender_id, c_cs)
            if not send_newtx(new_tx=c_tx, outer_cur=cur):
                raise BaseException('Failed to send new tx.')
            db.commit()
            data = {
                'txhash': hexlify(c_tx.hash).decode(),
                'c_address': c_address,
                'time': c_tx.time,
                'fee': {
                    'gas_price': c_tx.gas_price,
                    'gas_amount': c_tx.gas_amount,
                    'total': c_tx.gas_price * c_tx.gas_amount
                }
            }
            return web_base.json_res(data)
        except BaseException:
            return web_base.error_res()
예제 #9
0
async def validator_edit(request):
    start = time()
    post = await web_base.content_type_json_check(request)
    c_address = post.get('c_address', None)
    new_address = post.get('new_address', None)
    flag = int(post.get('flag', F_NOP))
    sig_diff = int(post.get('sig_diff', 0))
    try:
        with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
            cur = db.cursor()
            if c_address is None:
                c_address = create_new_user_keypair(name=C.ANT_NAME_CONTRACT,
                                                    cur=cur)
            tx = create_validator_edit_tx(c_address=c_address,
                                          new_address=new_address,
                                          flag=flag,
                                          sig_diff=sig_diff)
            if not send_newtx(new_tx=tx, outer_cur=cur):
                raise Exception('Failed to send new tx.')
            db.commit()
            return web_base.json_res({
                'hash': hexlify(tx.hash).decode(),
                'gas_amount': tx.gas_amount,
                'gas_price': tx.gas_price,
                'fee': tx.gas_amount * tx.gas_price,
                'time': round(time() - start, 3)
            })
    except Exception:
        return web_base.error_res()
예제 #10
0
def get_unspents_iter(outer_cur=None, best_chain=None):
    target_address = set()
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = outer_cur or db.cursor()
        for (uuid, address, user) in read_pooled_address_iter(cur):
            target_address.add(address)
    return get_utxo_iter(target_address=target_address, best_block=None, best_chain=best_chain)
예제 #11
0
파일: account.py 프로젝트: yoosofan/bc4py
def _callback(data_list):
    if isinstance(data_list[0], str):
        logging.error("Callback error, {}".format(data_list[0]))
        return
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        insert_keypairs(data_list, db.cursor())
        db.commit()
    logging.debug("Generate {} keypairs.".format(len(data_list)))
예제 #12
0
파일: utils.py 프로젝트: yoosofan/bc4py
def message2signature(raw, address):
    # sign by address
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        uuid, sk, pk = read_address2keypair(address, cur)
    if sk is None:
        raise BlockChainError('Not found address {}'.format(address))
    return pk, sign(msg=raw, sk=sk, pk=pk)
예제 #13
0
파일: utils.py 프로젝트: yoosofan/bc4py
def im_a_validator(best_block=None):
    validator_cks, required_num = get_validator_info(best_block)
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        for address in validator_cks:
            if read_address2user(address, cur):
                return address
    return None
예제 #14
0
def check_related_address(address_list):
    r = list()
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        for address in address_list:
            user = read_address2user(address=address, cur=cur)
            if user:
                r.append((read_user2name(user, cur), address))
    return r
예제 #15
0
async def list_balance(request):
    confirm = int(request.query.get('confirm', 6))
    users = user_account.get_balance(confirm)
    data = dict()
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        for user, balance in users.items():
            data[read_user2name(user, cur)] = balance.coins
    return web_base.json_res(data)
예제 #16
0
async def new_address(request):
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        user_name = request.query.get('account', C.ANT_NAME_UNKNOWN)
        user_id = read_name2user(user_name, cur)
        address = create_new_user_keypair(user_name, cur)
        db.commit()
        if user_id == C.ANT_CONTRACT:
            address = convert_address(address, V.BLOCK_CONTRACT_PREFIX)
    return web_base.json_res({'account': user_name, 'user_id': user_id, 'address': address})
예제 #17
0
def _debug(sql, path, explain=True):
    with closing(create_db(path)) as db:
        db.set_trace_callback(sql_info)
        cur = db.cursor()
        f = cur.execute(('explain query plan ' if explain else '') + sql)
        if explain:
            print(f.fetchone()[-1])
        else:
            c = 0
            for d in f.fetchall():
                print(c, ':', ', '.join(map(str, d)))
                c += 1
예제 #18
0
 def init(self):
     with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
         cur = db.cursor()
         memory_sum = UserCoins()
         for move_log in read_log_iter(cur):
             # logに記録されてもBlockに取り込まれていないならTXは存在せず
             if builder.db.read_tx(move_log.txhash):
                 memory_sum += move_log.movement
             else:
                 logging.warning("It's unknown log {}".format(move_log))
                 # delete_log(move_log.txhash, cur)
         self.db_balance += memory_sum
예제 #19
0
파일: editaccount.py 프로젝트: kmn/bc4py
async def lock_database(request):
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        if is_locked_database(cur):
            return web.Response(text='Already locked database.', status=400)
        new_key = AESCipher.create_key()
        change_encrypt_key(new_key, cur)
        V.ENCRYPT_KEY = new_key
        if is_locked_database(cur):
            return web.Response(text='Failed unlock check filed.', status=400)
        db.commit()
    return web_base.json_res({'key': new_key})
예제 #20
0
async def get_keypair(request):
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        try:
            address = request.query['address']
            uuid, sk, pk = read_address2keypair(address, cur)
            return web_base.json_res({
                'uuid': uuid,
                'address': address,
                'private_key': sk,
                'public_key': pk})
        except BlockChainError as e:
            return web.Response(text=str(e), status=400)
예제 #21
0
파일: editaccount.py 프로젝트: kmn/bc4py
async def unlock_database(request):
    post = await web_base.content_type_json_check(request)
    old_key = V.ENCRYPT_KEY
    V.ENCRYPT_KEY = post.get('password', None)
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        if is_locked_database(db.cursor()):
            V.ENCRYPT_KEY = old_key
            return web.json_response({
                'result': False,
                'status': 'locked'
            },
                                     status=400)
        else:
            return web_base.json_res({'result': True, 'status': 'unlocked'})
예제 #22
0
 def get_movement_iter(self, start=0, f_dict=False):
     count = 0
     with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
         cur = db.cursor()
         # Unconfirmed
         for tx in sorted(tx_builder.unconfirmed.values(),
                          key=lambda x: x.time,
                          reverse=True):
             move_log = read_txhash2log(tx.hash, cur)
             if move_log is None:
                 if tx.hash in self.memory_movement:
                     move_log = self.memory_movement[tx.hash]
             else:
                 if tx.hash in self.memory_movement:
                     move_log.pointer = self.memory_movement[
                         tx.hash].pointer
             if move_log:
                 if count >= start:
                     if f_dict:
                         yield move_log.get_dict_data(cur)
                     else:
                         yield move_log.get_tuple_data()
                 count += 1
         # Memory
         for block in reversed(builder.best_chain):
             for tx in block.txs:
                 move_log = read_txhash2log(tx.hash, cur)
                 if move_log is None:
                     if tx.hash in self.memory_movement:
                         move_log = self.memory_movement[tx.hash]
                 else:
                     if tx.hash in self.memory_movement:
                         move_log.pointer = self.memory_movement[
                             tx.hash].pointer
                 if move_log:
                     if count >= start:
                         if f_dict:
                             yield move_log.get_dict_data(cur)
                         else:
                             yield move_log.get_tuple_data()
                     count += 1
         # DataBase
         for move_log in read_log_iter(cur, start - count):
             # TRANSFERなど はDBとMemoryの両方に存在する
             if move_log.txhash in self.memory_movement:
                 continue
             elif f_dict:
                 yield move_log.get_dict_data(cur)
             else:
                 yield move_log.get_tuple_data()
예제 #23
0
async def list_account_address(request):
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        cur = db.cursor()
        user_name = request.query.get('account', C.ANT_NAME_UNKNOWN)
        user_id = read_name2user(user_name, cur)
        address_list = list()
        for uuid, address, user in read_pooled_address_iter(cur):
            if user_id == user:
                if user == C.ANT_CONTRACT:
                    address_list.append(convert_address(ck=address, prefix=V.BLOCK_CONTRACT_PREFIX))
                else:
                    address_list.append(address)
    return web_base.json_res({
        'account': user_name, 'user_id': user_id, 'address': address_list})
예제 #24
0
파일: account.py 프로젝트: yoosofan/bc4py
 def get_dict_data(self, outer_cur=None):
     with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
         cur = outer_cur or db.cursor()
         movement = {
             read_user2name(user, cur): coins.coins
             for user, coins in self.movement.items()
         }
     return {
         'txhash': hexlify(self.txhash).decode(),
         'height': self.height,
         'on_memory': self.on_memory,
         'type': C.txtype2name[self.type],
         'movement': movement,
         'time': self.time + V.BLOCK_GENESIS_TIME
     }
예제 #25
0
 def move_balance(self, _from, _to, coins, outer_cur=None):
     assert isinstance(coins, CoinObject),  'coins is CoinObject.'
     with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
         cur = outer_cur or db.cursor()
         try:
             # DataBaseに即書き込む(Memoryに入れない)
             movements = UserCoins()
             movements[_from] -= coins
             movements[_to] += coins
             txhash = insert_log(movements, cur)
             if outer_cur is None:
                 db.commit()
             self.db_balance += movements
             return txhash
         except BaseException:
             db.rollback()
예제 #26
0
파일: builder.py 프로젝트: kmn/bc4py
 def move_balance(self, _from, _to, coins, outer_cur=None):
     assert isinstance(coins, Balance), 'coins is Balance.'
     with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
         cur = outer_cur or db.cursor()
         try:
             # DataBaseに即書き込む(Memoryに入れない)
             movements = Accounting()
             movements[_from] -= coins
             movements[_to] += coins
             txhash = insert_log(movements, cur)
             if outer_cur is None:
                 db.commit()
             self.db_balance += movements
             return txhash
         except Exception:
             logging.error("Failed move_balance,", exc_info=True)
             db.rollback()
예제 #27
0
파일: builder.py 프로젝트: kmn/bc4py
 def init(self, f_delete=False):
     assert f_delete is False, 'Unsafe function!'
     with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
         cur = db.cursor()
         memory_sum = Accounting()
         for move_log in read_log_iter(cur):
             # logに記録されてもBlockに取り込まれていないならTXは存在せず
             if builder.db.read_tx(move_log.txhash):
                 memory_sum += move_log.movement
             else:
                 logging.debug("It's unknown log {}".format(move_log))
                 if f_delete:
                     delete_log(move_log.txhash, cur)
         if f_delete:
             logging.warning("Delete user's old unconfirmed tx.")
             db.commit()
         self.db_balance += memory_sum
예제 #28
0
async def move_many(request):
    try:
        post = await web_base.content_type_json_check(request)
        ant_from = post.get('from', C.ANT_NAME_UNKNOWN)
        ant_to = post['to']
        coins = CoinObject()
        for k, v in post['coins'].items():
            coins[int(k)] += int(v)
        with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
            cur = db.cursor()
            _from = read_name2user(ant_from, cur)
            _to = read_name2user(ant_to, cur)
            txhash = user_account.move_balance(_from, _to, coins, cur)
            db.commit()
        return web_base.json_res({
            'txhash': hexlify(txhash).decode(),
            'from_id': _from, 'to_id': _to})
    except Exception as e:
        return web.Response(text=str(e), status=400)
예제 #29
0
파일: editaccount.py 프로젝트: kmn/bc4py
async def change_password(request):
    post = await web_base.content_type_json_check(request)
    with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
        db.isolation_level = 'EXCLUSIVE'
        cur = db.cursor()
        old_key = V.ENCRYPT_KEY
        V.ENCRYPT_KEY = post.get('old', None)
        if is_locked_database(cur):
            V.ENCRYPT_KEY = old_key
            return web.Response(text='Failed to unlock database first of all.',
                                status=400)
        new_key = post.get('new', None)
        change_encrypt_key(new_key, cur)
        V.ENCRYPT_KEY = new_key
        if is_locked_database(cur):
            V.ENCRYPT_KEY = old_key
            return web.Response(
                text='Unlock success, but failed to change key.', status=400)
        db.commit()
    return web_base.json_res({'result': True})
예제 #30
0
파일: builder.py 프로젝트: kmn/bc4py
 def new_batch_apply(self, batched_blocks):
     with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
         cur = db.cursor()
         for block in batched_blocks:
             for tx in block.txs:
                 move_log = read_txhash2log(tx.hash, cur)
                 if move_log:
                     # User操作の記録
                     self.db_balance += move_log.movement
                     if tx.hash in self.memory_movement:
                         del self.memory_movement[tx.hash]
                     # logging.debug("Already recoded log {}".format(tx))
                 elif tx.hash in self.memory_movement:
                     # db_balanceに追加
                     _type, movement, _time = self.memory_movement[tx.hash].get_tuple_data()
                     self.db_balance += movement
                     # memory_movementから削除
                     del self.memory_movement[tx.hash]
                     # insert_log
                     insert_log(movement, cur, _type, _time, tx.hash)
         db.commit()