Ejemplo n.º 1
0
    def post(self):

        command_request = self.request.POST.get("command")

        trans = Transaction()

        trans.command = command_request
        trans.datetimestemp = datetime.now()
        trans.put()
Ejemplo n.º 2
0
    def get(self):

        # path = os.path.join(os.path.dirname(__file__), 'sensorside.html')

        query_command = Transaction.gql(
            "WHERE datetimestemp>:dt ORDER BY datetimestemp DESC", dt=(datetime.now() - timedelta(hours=1))
        )

        last_command = query_command.fetch(limit=1)[0]

        jsonStr = json.dumps(
            [{"last_command": last_command.command}, {"datetimestemp": str(last_command.datetimestemp)}]
        )

        self.response.headers["Content-Type"] = "application/json"
        self.response.out.write(jsonStr)
Ejemplo n.º 3
0
    def post(self):
        books = []
        args = calculate_parser.parse_args()
        req = request.json['books']
        user = Customer.query.filter(Customer.email == args['email']).first()

        if not user:
            user = Customer(name=args['name'], email=args['email'], phone_number=args['phone'])
            db.session.add(user)
            db.session.commit()
        for book in req:
            book = Books.query.get(book)
            assert book, abort(404, message=f"Book with Id <{book}> not found")
            books.append(book)
        currency_id = book.currency_id
        trans = Transaction.create_transaction(customer_id=user.id, currency_id=currency_id, books=books)
        return trans, 201
Ejemplo n.º 4
0
    def scan(self):
        self.block_info = self.rpc.get_block_height()
        self.newest_height = self.block_info.current_height
        self.highest_height = self.block_info.highest_height
        # 延迟扫 SCAN_DELAY_NUMBER 个块
        need_to_height = self.newest_height - self.SCAN_DELAY_NUMBER
        self.logger.info('起始扫块高度:{} 最新高度:{} 需要同步:{}'.format(
            self.current_scan_height, self.newest_height,
            need_to_height - self.current_scan_height))
        while self.current_scan_height < need_to_height:
            self.logger.info('当前已扫块高度:{} 最新高度:{} 需要同步:{}  节点最高高度:{}'.format(
                self.current_scan_height, self.newest_height,
                need_to_height - self.current_scan_height,
                self.highest_height))

            for height in range(self.current_scan_height, need_to_height,
                                self.SCAN_HEIGHT_NUMBER):
                # 分批处理, 一次处理 SCAN_HEIGHT_NUMBER 或 剩余要处理的块
                block_batch = min(self.SCAN_HEIGHT_NUMBER,
                                  need_to_height - self.current_scan_height)

                blocks = self.rpc.get_block_by_number([
                    digit.int_to_hex(height)
                    for height in range(height, height + block_batch)
                ])
                save_tx_count = 0
                with runtime.app.app_context():
                    # 一次处理一批
                    session = db.session()
                    try:
                        for block in blocks:
                            if block is None:
                                return
                            block_height = digit.hex_to_int(block['number'])
                            block_hash = block['hash']
                            block_timestamp = digit.hex_to_int(
                                block['timestamp'])
                            block_time = datetime.fromtimestamp(
                                block_timestamp)

                            session.begin(subtransactions=True)
                            db_block = Block(height=block_height,
                                             block_hash=block_hash,
                                             block_time=block_time)
                            session.add(db_block)
                            session.commit()

                            for transaction in block.get('transactions', []):
                                tx = EthereumResolver.resolver_transaction(
                                    transaction)
                                if tx.sender in runtime.project_address:
                                    # 提现的暂时不要
                                    continue
                                if tx.receiver in runtime.project_address:
                                    receipt_raw_tx = self.rpc.get_transaction_receipt(
                                        tx.tx_hash)
                                    if tx.contract:
                                        coin = runtime.coins.get(tx.contract)
                                    else:
                                        coin = runtime.coins.get(
                                            self.COIN_NAME)
                                    if coin is None:
                                        continue

                                    if receipt_raw_tx:
                                        receipt_tx = EthereumResolver.resolver_receipt(
                                            receipt_raw_tx)
                                    else:
                                        self.logger.error(
                                            '请求 {} receipt 错误, 重新处理')
                                        raise
                                    tx.status = receipt_tx.status
                                    # session.begin(subtransactions=True)
                                    # db_tx = Transaction(block_id=db_block.id, coin_id=coin['coin_id'],
                                    #                     tx_hash=tx.tx_hash, height=db_block.height,
                                    #                     block_time=block_timestamp,
                                    #                     amount=tx.value, sender=tx.sender, receiver=tx.receiver,
                                    #                     gas=tx.gas, gas_price=tx.gas_price,
                                    #                     is_send=SendEnum.NOT_PUSH.value,
                                    #                     fee=receipt_tx.gas_used * tx.gas_price,
                                    #                     contract=tx.contract, status=receipt_tx.status,
                                    #                     type=TxTypeEnum.DEPOSIT.value)
                                    Transaction.add_transaction_or_update(
                                        block_id=db_block.id,
                                        coin_id=coin['coin_id'],
                                        tx_hash=tx.tx_hash,
                                        height=db_block.height,
                                        block_time=block_timestamp,
                                        amount=tx.value,
                                        sender=tx.sender,
                                        receiver=tx.receiver,
                                        gas=tx.gas,
                                        gas_price=tx.gas_price,
                                        is_send=SendEnum.NOT_PUSH.value,
                                        fee=receipt_tx.gas_used * tx.gas_price,
                                        contract=tx.contract,
                                        status=receipt_tx.status,
                                        type=TxTypeEnum.DEPOSIT.value,
                                        session=session,
                                        commit=False)
                                    save_tx_count += 1
                                    # session.add(db_tx)
                                    # session.commit()
                                    # 添加推送信息

                        session.query(SyncConfig).filter(
                            SyncConfig.id == self.config_id).update({
                                'synced_height':
                                height + block_batch,
                                'highest_height':
                                self.highest_height
                            })
                        self.current_scan_height = height + block_batch
                        session.commit()
                        self.logger.info("本次同步高度为:{} -- {}, 保存交易: {} 笔".format(
                            height, height + block_batch, save_tx_count))

                    except Exception as e:
                        self.logger.error('同步块出现异常, 事务回滚. {}'.format(e))
                        session.rollback()
                        return
        self.logger.info("扫链结束, 本次同步")
Ejemplo n.º 5
0
    def render(self):
        self.logger.info('开始补充手续费进程')
        for pid, p in self.project_addresses.items():
            project_address = p['address']
            for ck, coin in runtime.coins.items():
                if coin['coin_name'] == self.COIN_NAME:
                    self.logger.warning('币种名称为: {}, 不需要补充手续费!'.format(
                        coin['coin_name']))
                    continue
                contract = coin['contract']
                offset, count = 0, self.BALANCE_QUERY_NUMBER
                for s in range(0, len(project_address), count):
                    addresses = project_address[offset:count]
                    balances = self.rpc.get_balance(addresses, contract)
                    balances_sum = sum([
                        digit.hex_to_int(balance) for balance in balances
                        if balance
                    ])
                    if not balances_sum:
                        self.logger.info("本 {} 个地址无额外, 不需要补充手续费".format(
                            len(addresses)))
                        continue
                    for idx, balance in enumerate(balances):
                        balance_int = hex_to_int(balance)
                        if not balance_int:
                            continue
                        balance_eth_int = hex_to_int(
                            self.rpc.get_balance(address=addresses[idx]))

                        if hasattr(config, 'GAS'):
                            gas = config.GAS
                        else:
                            gas = self.rpc.get_smart_fee(contract=contract)
                        if hasattr(config, 'GAS_PRICE'):
                            gas_price = config.GAS_PRICE
                        else:
                            gas_price = self.rpc.gas_price()
                        if gas is None:
                            self.logger.info("未找到合适 gas . {}".format(gas))
                            continue
                        if gas_price is None:
                            self.logger.info(
                                "未找到合适 gas_price . {}".format(gas_price))
                            continue
                        gas, gas_price = hex_to_int(gas), hex_to_int(gas_price)
                        fee = gas * gas_price

                        if balance_eth_int > fee:
                            self.logger.info("地址: {} 手续费足够, 不需要补充手续费".format(
                                addresses[idx]))
                            continue

                        render_amount = int(config.COLLECTION_MIN_ETH * 1e18)

                        tx_hash = self.rpc.send_transaction(
                            sender=config.RENDER_ADDRESS,
                            receiver=addresses[idx],
                            value=render_amount,
                            passphrase=p['passphrase'],
                            gas=gas,
                            gas_price=gas_price,
                            contract=contract)
                        if not tx_hash:
                            self.logger.error("给地址: {} 补充手续费失败".format(
                                addresses[idx]))
                            continue
                        self.logger.info("给地址: {} 补充手续费成功".format(
                            addresses[idx]))
                        with runtime.app.app_context():
                            saved = Transaction.add_transaction(
                                coin_id=coin['coin_id'],
                                tx_hash=tx_hash,
                                block_time=datetime.now().timestamp(),
                                sender=config.RENDER_ADDRESS,
                                receiver=addresses[idx],
                                amount=render_amount,
                                status=TxStatusEnum.UNKNOWN.value,
                                type=TxTypeEnum.RENDER.value,
                                block_id=-1,
                                height=-1,
                                gas=gas,
                                gas_price=gas_price,
                                contract=contract)
        self.logger.info('结束补充手续费进程')
Ejemplo n.º 6
0
    def collection(self):
        self.logger.info('开始归集进程')
        for pid, p in self.project_addresses.items():
            project_address = p['address']
            for ck, coin in runtime.coins.items():
                contract = coin['contract']
                offset, count = 0, self.BALANCE_QUERY_NUMBER
                for s in range(0, len(project_address), count):
                    addresses = project_address[offset:count]
                    balances = self.rpc.get_balance(addresses, contract)
                    balances_sum = sum([
                        digit.hex_to_int(balance) for balance in balances
                        if balance
                    ])
                    if not balances_sum:
                        self.logger.info("本 {} 个地址不需要归集".format(
                            len(addresses)))
                        continue
                    for idx, balance in enumerate(balances):
                        balance_int = hex_to_int(balance)
                        if not balance_int:
                            continue
                        if hasattr(config, 'GAS'):
                            gas = config.GAS
                        else:
                            gas = self.rpc.get_smart_fee(contract=contract)

                        if hasattr(config, 'GAS_PRICE'):
                            gas_price = config.GAS_PRICE
                        else:
                            gas_price = self.rpc.gas_price()

                        if gas is None:
                            self.logger.info("未找到合适 gas . {}".format(gas))
                            continue
                        if gas_price is None:
                            self.logger.info(
                                "未找到合适 gas_price . {}".format(gas_price))
                            continue

                        gas, gas_price = hex_to_int(gas), hex_to_int(gas_price)
                        fee = gas * gas_price
                        if coin['symbol'] == 'ETH':
                            send_value = max(
                                balance_int -
                                max(int(config.COLLECTION_MIN_ETH * 1e18),
                                    fee), 0)
                        else:
                            send_value = balance_int

                        if send_value <= 0:
                            self.logger.info("地址 {} 需要归集金额低于 0".format(
                                addresses[idx]))
                            continue

                        tx_hash = self.rpc.send_transaction(
                            sender=addresses[idx],
                            receiver=config.COLLECTION_ADDRESS,
                            value=send_value,
                            passphrase=p['passphrase'],
                            gas=gas,
                            gas_price=gas_price,
                            contract=contract)
                        with runtime.app.app_context():
                            saved = Transaction.add_transaction(
                                coin_id=coin['coin_id'],
                                tx_hash=tx_hash,
                                block_time=datetime.now().timestamp(),
                                sender=addresses[idx],
                                receiver=config.COLLECTION_ADDRESS,
                                amount=send_value,
                                status=TxStatusEnum.UNKNOWN.value,
                                type=TxTypeEnum.COLLECTION.value,
                                block_id=-1,
                                height=-1,
                                gas=gas,
                                gas_price=gas_price,
                                contract=contract)

                    offset += count
        self.logger.info("结束归集进程")
Ejemplo n.º 7
0
def get_tx_by_tx_hash(tx_hash: str):
    rpc = RpcConfig.get_rpc()
    if rpc is None:
        return ResponseObject.error(**out_data_missing)
    chain_info = rpc.get_block_height()

    tx = Transaction.get_tx_coin_by_tx_hash(tx_hash=tx_hash)
    if tx:
        return ResponseObject.success(
            data={
                "sender":
                tx.Transaction.sender,
                "receiver":
                tx.Transaction.receiver,
                "txHash":
                tx.Transaction.tx_hash,
                "value":
                safe_math.divided(tx.Transaction.amount,
                                  safe_math.e_calc(
                                      tx.Coin.decimal)).to_eng_string(),
                "blockHeight":
                tx.Transaction.height,
                "blockTime":
                tx.Transaction.block_time,
                "contract":
                tx.Transaction.contract,
                "isValid":
                True if tx.Transaction.status == 1 else False,
                "confirmNumber":
                chain_info.highest_height -
                tx.Transaction.height if tx.Transaction.height > 0 else 0
            })
    else:
        tx_origin, receipt_origin = rpc.get_transaction_by_hash(tx_hash)
        if tx_origin and receipt_origin:
            tx, receipt = EthereumResolver.resolver_transaction(
                tx_origin), EthereumResolver.resolver_receipt(receipt_origin)
            block_info = rpc.get_block_by_number(int_to_hex(tx.block_height),
                                                 False)
            if not block_info:
                return ResponseObject.error(**rpc_block_not_found)
            block = EthereumResolver.resolver_block(block_info, False)
            if tx.contract is not None:
                coin = Coin.get_erc20_usdt_coin()
            else:
                coin = Coin.get_coin(name='Ethereum')
            if coin is None:
                return ResponseObject.error(**coin_missing)
            return ResponseObject.success(
                data={
                    "sender":
                    tx.sender,
                    "receiver":
                    tx.receiver,
                    "txHash":
                    tx.tx_hash,
                    "value":
                    safe_math.divided(tx.value, safe_math.e_calc(
                        coin.decimal)).to_eng_string(),
                    "blockHeight":
                    tx.block_height,
                    "blockTime":
                    block.timestamp,
                    "contract":
                    tx.contract,
                    "isValid":
                    True if receipt.status == 1 else False,
                    "confirmNumber":
                    chain_info.highest_height - tx.block_height
                })
    return ResponseObject.error(**tx_miss)