示例#1
0
def check_block(block_info, operator: ERC20Token):
    """检查区块是否回滚"""
    if not block_info:
        return False
    info = operator.get_block(int(block_info.block_num) + 1)
    if not info:
        return False
    if hexstr_if_str(to_hex, info['parentHash']) == block_info.block_hash:
        new_block_info = {
            'block_num': int(info['number']),
            'block_hash': hexstr_if_str(to_hex, info['hash']),
            'coin_type': coin_type
        }
    else:
        new_block_info = {
            'coin_type': coin_type,
            'block_num':
            int(block_info.block_num) - int(config.eth_confirmations),
        }
        roll_back_info = operator.get_block(new_block_info['block_num'])
        new_block_info['block_hash'] = hexstr_if_str(to_hex,
                                                     roll_back_info['hash'])
        new_block_info = {
            'block_num': int(roll_back_info['number']),
            'block_hash': hexstr_if_str(to_hex, roll_back_info['hash']),
            'coin_type': coin_type
        }
    return new_block_info
示例#2
0
 def check_success(operator: ERC20Token, item):
     """检查是否成功
     :param operator: 区块链接口
     :param item: 交易信息
     :return:
     """
     res = operator.is_success(operator.get_transaction(item.txid))
     if res:
         return AskFeeStatusEnum.SUCCESS
     else:
         return AskFeeStatusEnum.FAILED
示例#3
0
 def withdraw_eth(cls, address, amount):
     private_key = hexstr_if_str(to_hex,
                                 load_keyfile(config.eth_private_key_file,
                                              config.eth_password)
                                 )
     eth = ERC20Token(provider_endpoint=config.eth_wallet_url,
                      private_key=private_key,
                      password=config.eth_password)
     checksum_address = eth.web3.toChecksumAddress(address)
     try:
         tx_id = eth.send_ether(checksum_address, amount)
         tb = {
             'amount': amount,
             'txid': tx_id,
             'coin_type': 'ETH',
             'from_address': config.eth_tb_address,
             'to_address': address,
             'status': TbStatusEnum.TRANSFER
         }
     except Exception as e:
         logger.exception(e)
     else:
         try:
             
             document = TbRecord(**tb)
             document.insert()
             return tx_id
         except Exception as e:
             logger.exception(e)
             logger.error("提币行为已经发生,但数据没有插入数据库{}".format(tb))
示例#4
0
    def send2address(self, address, amount, *args, **kwargs):
        password = config.etc_password
        private_key = hexstr_if_str(
            to_hex, load_keyfile(config.etc_private_key_file, password))
        eth = ERC20Token(ipc_path=config.etc_ipc_path,
                         private_key=private_key,
                         password=password)
        checksum_address = eth.web3.toChecksumAddress(address)
        try:
            tx_id = eth.send_ether(checksum_address, amount)
            tb = {
                'amount': amount,
                'txid': tx_id,
                'coin_type': 'ETC',
                'from_address': config.etc_tb_address,
                'to_address': address,
            }
        except Exception as e:
            logger.exception(e)
        else:
            try:

                document = TbRecord(**tb)
                document.insert()
                return tx_id
            except Exception as e:
                logger.exception(e)
                logger.error("提币行为已经发生,但数据没有插入数据库{}".format(tb))
示例#5
0
文件: erc_20.py 项目: buyongji/wallet
 def __init__(self, session_maker):
     """
     :param session_maker: mysql的session_maker
     """
     super().__init__(session_maker)
     self.coin_category = "ETH"
     self.chain_api = ERC20Token()
示例#6
0
def tx_process(session, tx_id, operator: ERC20Token):
    """交易处理函数"""

    tx_data = operator.get_transaction_data(tx_id)
    from_address = tx_data.from_address
    black_list = get_black_list()
    if from_address in black_list:
        return

    if not check_account_exists(session, tx_data.to_address):
        return

    coin = coin_type
    if tx_data.token_address:
        coin_info = session.query(coin_setting_document).filter_by(
            coin_setting_document.token_address.in_(
                (tx_data.token_address,
                 to_normalized_address(tx_data.token_address)))).first()
        if not coin_info:
            logger.error(f'not found token address: {tx_data.token_address}')
            return
        coin = coin_info.coin_type
        tx_data.token_amount = from_unit(tx_data.token_amount,
                                         coin_info.token_unit)

    recharge_record = session.query(coin_recharge_document).filter_by(
        txid=tx_id).first()
    if recharge_record:
        return

    data = {
        'amount': tx_data.ether_amount,
        'txid': tx_id,
        'created_at': datetime.utcnow(),
        'confirmation_count': tx_data.num_confirmations,
        'from_address': tx_data.from_address,
        'to_address': tx_data.to_address,
        'coin_type': coin,
        'coin_series': coin_type,
    }
    r = Recharge(**data)
    session.add(r)
    try:
        session.commit()
    except Exception as e:
        logger.exception("冲币记录到数据库时发生错误{}".format(e))
        session.rollback()
        raise
    else:
        recharge(address=data["to_address"],
                 from_address=data["from_address"],
                 amount=float(data["amount"]),
                 txid=data["txid"],
                 coin_type=data["coin_type"],
                 confirmations=data["confirmation_count"],
                 status=0,
                 destination_tag=None)
        logger.info('检测到{}充币到{}{}个'.format(tx_data.from_address,
                                           tx_data.to_address,
                                           tx_data.ether_amount))
示例#7
0
def main():
    session = Session()
    init_block_info(session)
    while True:
        try:
            operator = ERC20Token(provider_endpoint=config.eth_wallet_url)
            # 获取区块信息及交易列表
            block_info = session.query(block_info_document).filter_by(
                coin_type=coin_type).first()
            checked_block_info = check_block(block_info, operator)

            if not checked_block_info:
                continue

            tx_list = operator.get_block_tx_id_list(
                checked_block_info['block_num'])
            # 遍历交易列表
            for tx_id in tx_list:
                tx_process(session, hexstr_if_str(to_hex, tx_id), operator)
            logger.info(
                f'pull block finished: {checked_block_info["block_num"]}')
        except Exception as e:
            logger.exception(e)
        else:
            block_info.block_hash = checked_block_info['block_hash']
            block_info.block_num = checked_block_info['block_num']
            try:
                session.commit()
            except Exception as e:
                logger.exception("更新区块发生错误{}".format(e))
                session.rollback()
        time.sleep(3)
示例#8
0
def init_block_info(session):
    """第一次初始化数据库区块信息"""
    block_info = session.query(BlockInfo).filter_by(
        coin_type=coin_type).first()
    if block_info:
        return

    while True:
        try:
            operator = ERC20Token(provider_endpoint=config.eth_wallet_url)
            info = operator.get_block(int(operator.get_block_number()))
            block_info = BlockInfo(
                **{
                    'block_num': int(info['number']),
                    'block_hash': hexstr_if_str(to_hex, info['hash']),
                    'coin_type': coin_type
                })
            session.add(block_info)
            session.commit()
            logger.info('block_info init success')
            break
        except Exception as e:
            logger.exception("初始化区块失败{}".format(e))
            session.rollback()
        time.sleep(15)
示例#9
0
 def __init__(self, configure):
     self.coin_type = configure.coin_type
     self.block_record = BlockInfoRecord(configure)
     self.token_address = CoinSettingRecord(configure).token_address
     self.wallet_op = ERC20Token()
     self.tb_address = configure.tb_address
     self.confirmation_count = configure.confirmation_count
     try:
         self.block_num, self.block_hash = self.block_record.retrieve_head_block(
         )
     except RecordNotFound as e:
         logger.exception(e)
         self.block_num, self.block_hash = self._retrieve_head_block()
示例#10
0
 def withdraw_token(cls, to_address, amount, coin_type):
     token_info = CoinSetting.find_one({'id': coin_type,
                                        'main_coin': 'ETH'})
     if not token_info:
         logger.warning('不存在的币种类型{}'.format(coin_type))
         return
     token_address = token_info['token_address']
     private_key = hexstr_if_str(to_hex,
                                 load_keyfile(config.eth_private_key_file,
                                              config.eth_password)
                                 )
     token = ERC20Token(
         provider_endpoint=config.eth_wallet_url,
         contract_address=token_address,
         password=config.eth_password,
         private_key=private_key)
     try:
         tx_id = token.send_tokens(to_address, amount,
                                   token_info['token_unit'])
         data = {
             'amount': amount,
             'txid': tx_id,
             'from_address': getattr(config, f'{coin_type}_tb_address'),
             'coin_type': coin_type,
             'to_address': to_address,
             'status': TbStatusEnum.TRANSFER
         }
         logger.info('withdraw {} to {}'.format(coin_type, to_address))
     except Exception as e:
         logger.exception(e)
     else:
         try:
             tb = TbRecord(**data)
             tb.insert()
             return tx_id
         except Exception as e:
             logger.exception(e)
             logger.error("提币行为已经发生,但数据没有插入数据库{}".format(data))