Exemplo n.º 1
0
async def sign_raw_tx(request):
    post = await utils.content_type_json_check(request)
    try:
        binary = a2b_hex(post['hex'])
        other_pairs = dict()
        for sk in post.get('pairs', list()):
            sk = a2b_hex(sk)
            keypair: PyKeyPair = PyKeyPair.from_secret_key(sk)
            r, s = keypair.get_single_sign(binary)
            pk = keypair.get_public_key()
            ck = get_address(pk=pk, hrp=V.BECH32_HRP, ver=C.ADDR_NORMAL_VER)
            other_pairs[ck] = (pk, r, s)
        tx = TX.from_binary(binary=binary)
        for txhash, txindex in tx.inputs:
            input_tx = tx_builder.get_tx(txhash)
            address, coin_id, amount = input_tx.outputs[txindex]
            try:
                tx.signature.append(
                    sign_message_by_address(raw=tx.b, address=address))
            except BlockChainError:
                if address not in other_pairs:
                    raise BlockChainError(
                        'Not found secret key "{}"'.format(address))
                tx.signature.append(other_pairs[address])
        data = tx.getinfo()
        return utils.json_res({
            'hash': data['hash'],
            'signature': data['signature'],
            'hex': tx.b.hex()
        })
    except Exception:
        return utils.error_res()
Exemplo n.º 2
0
async def system_private_info(request):
    try:
        data = {
            'system_ver':
            __version__,
            'api_ver':
            __api_version__,
            'chain_ver':
            __chain_version__,
            'branch':
            V.BRANCH_NAME,
            'message':
            __message__,
            'booting':
            P.F_NOW_BOOTING,
            'connections':
            len(V.P2P_OBJ.core.user),
            'unconfirmed':
            [txhash.hex() for txhash in tx_builder.unconfirmed.keys()],
            'directory':
            V.DB_HOME_DIR,
            'generate_threads': [str(s) for s in generating_threads],
            'access_time':
            int(time()),
            'start_time':
            start_time
        }
        return utils.json_res(data)
    except Exception:
        return utils.error_res()
Exemplo n.º 3
0
async def get_mintcoin_info(request):
    try:
        mint_id = int(request.query.get('mint_id', 0))
        m = get_mintcoin_object(coin_id=mint_id)
        return utils.json_res(m.info)
    except Exception:
        return utils.error_res()
Exemplo n.º 4
0
async def conclude_contract(request):
    start = time()
    post = await utils.content_type_json_check(request)
    try:
        start_hash = a2b_hex(post['start_hash'])
        start_tx = tx_builder.get_tx(txhash=start_hash)
        if start_tx is None:
            return utils.error_res('Not found start_tx {}'.format(
                post['start_hash']))
        c_address, c_method, redeem_address, c_args = start_tx.encoded_message(
        )
        send_pairs = post.get('send_pairs', None)
        c_storage = post.get('storage', None)
        tx = create_conclude_tx(c_address=c_address,
                                start_tx=start_tx,
                                redeem_address=redeem_address,
                                send_pairs=send_pairs,
                                c_storage=c_storage)
        if not send_newtx(new_tx=tx):
            raise Exception('Failed to send new tx')
        return utils.json_res({
            'hash': tx.hash.hex(),
            '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 utils.error_res()
Exemplo n.º 5
0
async def list_account_address(request):
    with create_db(V.DB_ACCOUNT_PATH) as db:
        cur = db.cursor()
        user_name = request.query.get('account', C.account2name[C.ANT_UNKNOWN])
        user_id = read_name2userid(user_name, cur)
        address_list = list()
        for uuid, address, user in read_pooled_address_iter(cur):
            if user_id == user:
                if user == C.ANT_VALIDATOR:
                    address_list.append(
                        convert_address(ck=address,
                                        hrp=V.BECH32_HRP,
                                        ver=C.ADDR_VALIDATOR_VER))
                elif user == C.ANT_CONTRACT:
                    address_list.append(
                        convert_address(ck=address,
                                        hrp=V.BECH32_HRP,
                                        ver=C.ADDR_CONTRACT_VER))
                else:
                    address_list.append(address)
    return utils.json_res({
        'account': user_name,
        'user_id': user_id,
        'address': address_list
    })
Exemplo n.º 6
0
async def list_unspents(request):
    if not chain_builder.db.db_config['addrindex']:
        return utils.error_res('address isn\'t full indexed')
    try:
        best_height = chain_builder.best_block.height
        page = int(request.query.get('page', 0))
        limit = min(100, int(request.query.get('limit', 25)))
        start = page * limit
        finish = (page + 1) * limit - 1
        f_next_page = False
        target_address = request.query['address']
        unspents_iter = get_unspents_iter(
            target_address=set(target_address.split(',')))
        data = list()
        for index, (address, height, txhash, txindex, coin_id,
                    amount) in enumerate(unspents_iter):
            if finish < index:
                f_next_page = True
                break
            if index < start:
                continue
            data.append({
                'address': address,
                'height': height,
                'confirmed': None if height is None else best_height - height,
                'txhash': txhash.hex(),
                'txindex': txindex,
                'coin_id': coin_id,
                'amount': amount
            })
        return utils.json_res({'data': data, 'next': f_next_page})
    except Exception:
        return utils.error_res()
Exemplo n.º 7
0
async def contract_transfer(request):
    start = time()
    post = await utils.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.account2name[C.ANT_UNKNOWN])
        with create_db(V.DB_ACCOUNT_PATH) as db:
            cur = db.cursor()
            sender = read_name2userid(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 utils.json_res({
            'hash': tx.hash.hex(),
            '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 utils.error_res()
Exemplo n.º 8
0
async def validator_edit(request):
    start = time()
    post = await utils.content_type_json_check(request)
    v_address = post.get('v_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 create_db(V.DB_ACCOUNT_PATH) as db:
            cur = db.cursor()
            if v_address is None:
                v_address = generate_new_address_by_userid(
                    user=C.ANT_VALIDATOR, cur=cur)
            tx = create_validator_edit_tx(v_address=v_address,
                                          cur=cur,
                                          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 utils.json_res({
                'hash': tx.hash.hex(),
                '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 utils.error_res()
Exemplo n.º 9
0
async def validate_unconfirmed(request):
    start = time()
    post = await utils.content_type_json_check(request)
    try:
        txhash = a2b_hex(post['hash'])
        tx = tx_builder.get_tx(txhash=txhash)
        if tx is None or tx.height is not None:
            return utils.error_res('You cannot validate tx. {}'.format(tx))
        with 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 utils.json_res({
                'hash': new_tx.hash.hex(),
                '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 utils.error_res()
Exemplo n.º 10
0
async def issue_mint_tx(request):
    start = time()
    post = await utils.content_type_json_check(request)
    with create_db(V.DB_ACCOUNT_PATH, f_strict=True) as db:
        cur = db.cursor()
        try:
            user_name = post.get('from', C.account2name[C.ANT_UNKNOWN])
            sender = read_name2userid(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 BlockChainError('Failed to send new tx')
            db.commit()
            return utils.json_res({
                'hash': tx.hash.hex(),
                '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 Exception:
            return utils.error_res()
Exemplo n.º 11
0
async def change_mint_tx(request):
    start = time()
    post = await utils.content_type_json_check(request)
    with create_db(V.DB_ACCOUNT_PATH, f_strict=True) as db:
        cur = db.cursor()
        try:
            user_name = post.get('from', C.account2name[C.ANT_UNKNOWN])
            sender = read_name2userid(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 BlockChainError('Failed to send new tx')
            db.commit()
            return utils.json_res({
                'hash': tx.hash.hex(),
                '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 utils.error_res()
Exemplo n.º 12
0
async def create_wallet(request):
    try:
        post = await utils.content_type_json_check(request)
        passphrase = str(post.get('passphrase', ''))
        length = int(post.get('length', 256))
        if length not in length_list:
            return utils.error_res('length is {}'.format(length_list))
        mnemonic = Mnemonic(language).generate(length)
        seed = Mnemonic.to_seed(mnemonic, passphrase)
        root = Bip32.from_entropy(seed)
        bip = root.child_key(44 + BIP32_HARDEN).child_key(C.BIP44_COIN_TYPE)
        # keystone.json format
        return utils.json_res({
            'mnemonic':
            mnemonic,
            'passphrase':
            passphrase,
            'account_secret_key':
            bip.extended_key(True),
            'account_public_key':
            bip.extended_key(False),
            'path':
            bip.path,
            'comment':
            'You must recode "mnemonic" and "passphrase" and remove after. '
            'You can remove "account_secret_key" but you cannot sign and create new account',
        })
    except Exception:
        return utils.error_res()
Exemplo n.º 13
0
async def get_tx_by_hash(request):
    try:
        f_pickled = request.query.get('pickle', False)
        txhash = request.query.get('hash')
        txhash = a2b_hex(txhash)
        tx = tx_builder.get_tx(txhash)
        if tx is None:
            return web.Response(text="Not found tx", status=400)
        if f_pickled:
            tx = pickle.dumps(tx)
            return utils.json_res(b64encode(tx).decode())
        data = tx.getinfo()
        data['hex'] = tx.b.hex()
        return utils.json_res(data)
    except Exception as e:
        return utils.error_res()
Exemplo n.º 14
0
async def get_block_by_height(request):
    f_pickled = request.query.get('pickle', False)
    with_tx_info = request.query.get('txinfo', 'false')
    try:
        height = int(request.query['height'])
    except Exception as e:
        return web.Response(text="Height is not specified", status=400)
    blockhash = chain_builder.get_block_hash(height)
    if blockhash is None:
        return web.Response(text="Not found height", status=400)
    block = chain_builder.get_block(blockhash)
    if f_pickled:
        block = pickle.dumps(block)
        return utils.json_res(b64encode(block).decode())
    data = block.getinfo(with_tx_info == 'true')
    data['hex'] = block.b.hex()
    return utils.json_res(data)
Exemplo n.º 15
0
async def list_balance(request):
    confirm = int(request.query.get('confirm', 6))
    data = dict()
    with create_db(V.DB_ACCOUNT_PATH) as db:
        cur = db.cursor()
        users = user_account.get_balance(confirm=confirm, outer_cur=cur)
        for user, balance in users.items():
            data[read_userid2name(user, cur)] = dict(balance)
    return utils.json_res(data)
Exemplo n.º 16
0
async def source_compile(request):
    post = await utils.content_type_json_check(request)
    # Warning: do not execute unknown source code!
    try:
        c_obj = path2contract(path=post['path'])
        c_bin = contract2binary(c_obj)
        c_dis = contract2dis(c_obj)
        return utils.json_res({'hex': c_bin.hex(), 'dis': c_dis})
    except Exception:
        return utils.error_res()
Exemplo n.º 17
0
async def get_block_by_hash(request):
    try:
        f_pickled = request.query.get('pickle', False)
        with_tx_info = request.query.get('txinfo', 'false')
        blockhash = request.query.get('hash')
        if blockhash is None:
            return web.Response(text="Not found height", status=400)
        blockhash = a2b_hex(blockhash)
        block = chain_builder.get_block(blockhash)
        if block is None:
            return web.Response(text="Not found block", status=400)
        if f_pickled:
            block = pickle.dumps(block)
            return utils.json_res(b64encode(block).decode())
        data = block.getinfo(with_tx_info == 'true')
        data['size'] = block.size
        data['hex'] = block.b.hex()
        return utils.json_res(data)
    except Exception as e:
        return utils.error_res()
Exemplo n.º 18
0
async def get_validator_history(request):
    try:
        v_address = request.query['v_address']
        data = list()
        # database
        for index, new_address, flag, txhash, sig_diff in chain_builder.db.read_validator_iter(
                v_address=v_address):
            data.append({
                'index': index,
                'height': index // 0xffffffff,
                'new_address': new_address,
                'flag': flag,
                'txhash': txhash.hex(),
                'sig_diff': sig_diff
            })
        # memory
        for block in reversed(chain_builder.best_chain):
            for tx in block.txs:
                if tx.type != C.TX_VALIDATOR_EDIT:
                    continue
                _c_address, new_address, flag, sig_diff = tx.encoded_message()
                if _c_address != v_address:
                    continue
                index = validator_tx2index(tx=tx)
                data.append({
                    'index': index,
                    'height': tx.height,
                    'new_address': new_address,
                    'flag': flag,
                    'txhash': tx.hash.hex(),
                    'sig_diff': sig_diff
                })
        # unconfirmed
        for tx in sorted(tx_builder.unconfirmed.values(),
                         key=lambda x: x.create_time):
            if tx.type != C.TX_VALIDATOR_EDIT:
                continue
            _c_address, new_address, flag, sig_diff = tx.encoded_message()
            if _c_address != v_address:
                continue
            data.append({
                'index': None,
                'height': None,
                'new_address': new_address,
                'flag': flag,
                'txhash': tx.hash.hex(),
                'sig_diff': sig_diff
            })
        return utils.json_res(data)
    except Exception as e:
        log.error(e)
        return utils.error_res()
Exemplo n.º 19
0
async def contract_storage(request):
    try:
        c_address = request.query['c_address']
        f_confirmed = bool(request.query.get('confirmed', False))
        stop_hash = request.query.get('stophash', None)
        if stop_hash:
            stop_hash = a2b_hex(stop_hash)
        f_pickle = bool(request.query.get('pickle', False))
        best_block = chain_builder.best_block if f_confirmed else None
        c = get_contract_object(c_address=c_address,
                                best_block=best_block,
                                stop_txhash=stop_hash)
        if c is None:
            return utils.json_res({})
        elif f_pickle:
            storage = b64encode(pickle.dumps(c.storage)).decode()
        else:
            storage = {decode(k): decode(v) for k, v in c.storage.items()}
        return utils.json_res(storage)
    except Exception as e:
        log.error(e)
        return utils.error_res()
Exemplo n.º 20
0
async def chain_fork_info(request):
    try:
        main_chain = [block.getinfo() for block in chain_builder.best_chain]
        orphan_chain = [
            block.getinfo() for block in chain_builder.chain.values()
            if block not in chain_builder.best_chain
        ]
        data = {
            'main': main_chain,
            'orphan': sorted(orphan_chain, key=lambda x: x['height']),
            'root': chain_builder.root_block.getinfo()
        }
        return utils.json_res(data)
    except Exception:
        return utils.error_res()
Exemplo n.º 21
0
async def validator_info(request):
    try:
        v_address = request.query['v_address']
        f_confirmed = bool(request.query.get('confirmed', False))
        stop_hash = request.query.get('stophash', None)
        if stop_hash:
            stop_hash = a2b_hex(stop_hash)
        best_block = chain_builder.best_block if f_confirmed else None
        v = get_validator_object(v_address=v_address,
                                 best_block=best_block,
                                 stop_txhash=stop_hash)
        return utils.json_res(v.info)
    except Exception as e:
        log.error(e)
        return utils.error_res()
Exemplo n.º 22
0
async def get_keypair(request):
    try:
        with create_db(V.DB_ACCOUNT_PATH) as db:
            cur = db.cursor()
            address = request.query['address']
            uuid, keypair, path = read_address2keypair(address, cur)
            return utils.json_res({
                'uuid': uuid,
                'address': address,
                'private_key': keypair.get_secret_key().hex(),
                'public_key': keypair.get_public_key().hex(),
                'path': path
            })
    except Exception:
        return utils.error_res()
Exemplo n.º 23
0
async def list_transactions(request):
    page = int(request.query.get('page', 0))
    limit = int(request.query.get('limit', 25))
    data = list()
    f_next_page = False
    start = page * limit
    for tx_dict in user_account.get_movement_iter(start=page, f_dict=True):
        if limit == 0:
            f_next_page = True
            break
        tx_dict['index'] = start
        data.append(tx_dict)
        start += 1
        limit -= 1
    return utils.json_res({'txs': data, 'next': f_next_page})
Exemplo n.º 24
0
async def get_mintcoin_history(request):
    try:
        mint_id = int(request.query.get('mint_id', 0))
        data = list()
        for index, txhash, params, setting in chain_builder.db.read_coins_iter(
                coin_id=mint_id):
            data.append({
                'index': index,
                'txhash': txhash.hex(),
                'params': params,
                'setting': setting
            })
        return utils.json_res(data)
    except Exception:
        return utils.error_res()
Exemplo n.º 25
0
async def watching_info(request):
    try:
        # You need to enable watching option!
        return utils.json_res([{
            'hash': txhash.hex(),
            'type': tx.type,
            'tx': str(tx),
            'time': time,
            'c_address': c_address,
            'related': related_list,
            'args': tuple(map(decode, args)),
        } for txhash, (time, tx, related_list, c_address,
                       *args) in watching_tx.items()])
    except Exception as e:
        log.error(e)
        return utils.error_res()
Exemplo n.º 26
0
async def chain_info(request):
    try:
        best_height = chain_builder.best_block.height
        best_block = chain_builder.best_block
        old_block_height = chain_builder.best_chain[0].height - 1
        old_block_hash = chain_builder.get_block_hash(old_block_height).hex()
        data = {'best': best_block.getinfo()}
        difficulty = dict()
        for consensus, ratio in V.BLOCK_CONSENSUSES.items():
            name = C.consensus2name[consensus]
            bits, target = get_bits_by_hash(previous_hash=best_block.hash,
                                            consensus=consensus)
            target = float(target)
            block_time = round(V.BLOCK_TIME_SPAN / ratio * 100)
            diff = round(DEFAULT_TARGET / target, 8)
            bias = get_bias_by_hash(previous_hash=best_block.previous_hash,
                                    consensus=consensus)
            difficulty[name] = {
                'number':
                consensus,
                'bits':
                bits.to_bytes(4, 'big').hex(),
                'diff':
                round(diff, 8),
                'bias':
                round(bias, 8),
                'fixed_diff':
                round(diff / bias, 8),
                'hashrate(kh/s)':
                round((MAX_256_FLOAT / target) / block_time / 1000, 3)
            }
        data['mining'] = difficulty
        data['size'] = best_block.size
        data['checkpoint'] = {
            'height': old_block_height,
            'blockhash': old_block_hash
        }
        data['money_supply'] = GompertzCurve.calc_total_supply(best_height)
        data['total_supply'] = GompertzCurve.k
        if F_ADD_CASHE_INFO:
            data['cashe'] = {
                'get_bits_by_hash': str(get_bits_by_hash.cache_info()),
                'get_bias_by_hash': str(get_bias_by_hash.cache_info())
            }
        return utils.json_res(data)
    except Exception:
        return utils.error_res()
Exemplo n.º 27
0
async def list_private_unspents(request):
    data = list()
    best_height = chain_builder.best_block.height
    with create_db(V.DB_ACCOUNT_PATH) as db:
        cur = db.cursor()
        for address, height, txhash, txindex, coin_id, amount in get_my_unspents_iter(
                cur):
            data.append({
                'address': address,
                'height': height,
                'confirmed': None if height is None else best_height - height,
                'txhash': txhash.hex(),
                'txindex': txindex,
                'coin_id': coin_id,
                'amount': amount
            })
    return utils.json_res(data)
Exemplo n.º 28
0
async def send_from_user(request):
    start = time()
    if P.F_NOW_BOOTING:
        return web.Response(text='Now booting', status=403)
    post = await utils.content_type_json_check(request)
    with create_db(V.DB_ACCOUNT_PATH, f_strict=True) as db:
        cur = db.cursor()
        try:
            from_name = post.get('from', C.account2name[C.ANT_UNKNOWN])
            from_id = read_name2userid(from_name, cur)
            to_address = post['address']
            coin_id = int(post.get('coin_id', 0))
            amount = int(post['amount'])
            coins = Balance(coin_id, amount)
            if 'hex' in post:
                msg_type = C.MSG_BYTE
                msg_body = a2b_hex(post['hex'])
            elif 'message' in post:
                msg_type = post.get('message_type', C.MSG_PLAIN)
                msg_body = type2message(msg_type, post['message'])
            else:
                msg_type = C.MSG_NONE
                msg_body = b''
            new_tx = send_from(from_id,
                               to_address,
                               coins,
                               cur,
                               msg_type=msg_type,
                               msg_body=msg_body)
            if 'R' in post:
                new_tx.R = a2b_hex(post['R'])
            if not send_newtx(new_tx=new_tx, outer_cur=cur):
                raise BlockChainError('Failed to send new tx')
            db.commit()
            return utils.json_res({
                'hash': new_tx.hash.hex(),
                '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 as e:
            db.rollback()
            return utils.error_res()
Exemplo n.º 29
0
async def import_private_key(request):
    try:
        post = await utils.content_type_json_check(request)
        sk = a2b_hex(post['private_key'])
        ck = post['address']
        name = post.get('account', C.account2name[C.ANT_UNKNOWN])
        keypair: PyKeyPair = PyKeyPair.from_secret_key(sk)
        check_ck = get_address(pk=keypair.get_public_key(),
                               hrp=V.BECH32_HRP,
                               ver=C.ADDR_NORMAL_VER)
        if ck != check_ck:
            return utils.error_res('Don\'t match, {}!={}'.format(ck, check_ck))
        with create_db(V.DB_ACCOUNT_PATH) as db:
            cur = db.cursor()
            user = read_name2userid(name=name, cur=cur)
            insert_keypair_from_outside(sk=sk, ck=ck, user=user, cur=cur)
            db.commit()
        return utils.json_res({'status': True})
    except Exception:
        return utils.error_res()
Exemplo n.º 30
0
async def broadcast_tx(request):
    start = time()
    post = await utils.content_type_json_check(request)
    try:
        binary = a2b_hex(post['hex'])
        new_tx = TX.from_binary(binary=binary)
        new_tx.signature = [(a2b_hex(pk), a2b_hex(sig))
                            for pk, sig in post['signature']]
        if 'R' in post:
            new_tx.R = a2b_hex(post['R'])
        if not send_newtx(new_tx=new_tx):
            raise BlockChainError('Failed to send new tx')
        return utils.json_res({
            'hash': new_tx.hash.hex(),
            '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 utils.error_res()