Commit 1be0b88e by wangfa

Merge remote-tracking branch 'origin/master'

parents 79ebf1e9 294f883a
import re
import time
import json
import redis
import random
import aiohttp
import requests
from web3 import Web3
from web3.eth import AsyncEth
import datetime
import itertools
import eth_utils
import numpy as np
from lxml import etree
from fake_useragent import UserAgent
from aredis import StrictRedis, ConnectionPool
from web3._utils.abi import get_abi_output_types, map_abi_data
from web3._utils.normalizers import BASE_RETURN_NORMALIZERS
uni256Max = 2 ** 256
......@@ -156,22 +143,6 @@ class RedisCon:
print("Redis lrem error:", e)
@staticmethod
def ex_data(key, v_time, value):
"""
redis setex
:param key:
:param v_time:
:param value:
:return:
"""
redis_con = redis.Redis(connection_pool=RedisConnSingleton())
try:
redis_con.setex(key, v_time, value)
except Exception as e:
print("Redis setex error:", e)
@staticmethod
def get_task_num(key):
"""
redis llen
......@@ -303,1306 +274,6 @@ class Helper:
except Exception as e:
print("Redis lpop error:", e)
@staticmethod
async def save_hash_data(redis_key, key, value):
"""
aredis hset
:param redis_key:
:param key:
:param value:
:return:
"""
redis_con = StrictRedis(connection_pool=RedisConnectionPoolSingleton())
try:
await redis_con.hset(redis_key, key, value)
except Exception as e:
print("Redis hset error", e)
@staticmethod
async def del_hash_data(redis_key, key):
"""
aredis hdel
:param redis_key:
:param key:
:return:
"""
redis_con = StrictRedis(connection_pool=RedisConnectionPoolSingleton())
try:
await redis_con.hdel(redis_key, key)
except Exception as e:
print("Redis hdel error", e)
@staticmethod
async def get_string_value(name):
"""
aredis get
:param name:
:return:
"""
redis_con = StrictRedis(connection_pool=RedisConnectionPoolSingleton())
try:
data = await redis_con.get(name)
return data
except Exception as e:
print("Redis get error", e)
@staticmethod
async def ex_data(key, time, value):
"""
aredis setex
:param key:
:param time:
:param value:
:return:
"""
redis_con = StrictRedis(connection_pool=RedisConnectionPoolSingleton())
try:
await redis_con.setex(key, time, value)
except Exception as e:
print("Redis setex error", e)
@staticmethod
async def get_functions_(fn_abi, transaction, web_async):
"""
web3 get_functions_
:param fn_abi:
:param transaction:
:param web_async:
:return:
"""
eth = AsyncEth(web_async)
contract = await eth.call(transaction)
output_types = get_abi_output_types(fn_abi)
output_data = web_async.codec.decode_abi(output_types, contract)
_normalizers = itertools.chain(
BASE_RETURN_NORMALIZERS,
(),
)
normalized_data = map_abi_data(_normalizers, output_types, output_data)
# print(normalized_data)
if len(normalized_data) == 1:
return normalized_data[0]
else:
return normalized_data
@staticmethod
async def get_token_decimals(token, web_async):
"""
web3 decimals
:param token:
:param web_async:
:return:
"""
fn_abi = {'inputs': [], 'name': 'decimals', 'outputs': [{'internalType': 'uint8', 'name': '', 'type': 'uint8'}],
'stateMutability': 'view', 'type': 'function'}
transaction = {'to': f'{token}', 'data': '0x313ce567'}
function = await Helper.get_functions_(fn_abi, transaction, web_async)
# print("decimals", function)
return function
@staticmethod
async def get_token_name(token, web_async):
"""
web3 name
:param token:
:param web_async:
:return:
"""
fn_abi = {'inputs': [], 'name': 'name', 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
'stateMutability': 'view', 'type': 'function'}
transaction = {'to': f'{token}', 'data': '0x06fdde03'}
function = await Helper.get_functions_(fn_abi, transaction, web_async)
# print("name", function)
return function
@staticmethod
async def get_token_supply(token, web_async):
"""
web3 supply
:param token:
:param web_async:
:return:
"""
fn_abi = {'inputs': [], 'name': 'totalSupply',
'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], 'stateMutability': 'view',
'type': 'function'}
transaction = {'to': f'{token}', 'data': '0x18160ddd'}
function = await Helper.get_functions_(fn_abi, transaction, web_async)
# print("total supply", function)
return function
@staticmethod
async def get_token_symbol(token, web_async):
"""
web3 symbol
:param token:
:param web_async:
:return:
"""
fn_abi = {'inputs': [], 'name': 'symbol', 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
'stateMutability': 'view', 'type': 'function'}
transaction = {'to': f'{token}', 'data': '0x95d89b41'}
function = await Helper.get_functions_(fn_abi, transaction, web_async)
# print("symbol", function)
return function
@staticmethod
async def get_token_balance(token, address, web_async):
"""
web3 balanceOf
:param token:
:param address:
:param web_async:
:return:
"""
fn_abi = {'inputs': [{'internalType': 'address', 'name': '', 'type': 'address'}], 'name': 'balanceOf',
'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], 'stateMutability': 'view',
'type': 'function'}
address = '0x70a08231000000000000000000000000' + (address.lower()[2:])
transaction = {'to': f'{token}', 'data': address}
function = await Helper.get_functions_(fn_abi, transaction, web_async)
# print("token balance", function)
return function
@staticmethod
def trans_address_n0x(address):
"""
address type change
:param address:
:return:
"""
address = address[2:]
while len(address) < 64:
address = '0' + address
return address.lower()
@staticmethod
async def get_amounts_out_op(token0, token1, web_async, Router, token0_d):
"""
get price rate - op
:param token0:
:param token1:
:param web_async:
:param Router:
:param token0_d:
:return:
"""
fn_abi = {'inputs': [{'internalType': 'uint256', 'name': 'amountIn', 'type': 'uint256'},
{'internalType': 'address[]', 'name': 'path', 'type': 'address[]'}],
'name': 'getAmountsOut',
'outputs': [{'internalType': 'uint256[]', 'name': 'amounts', 'type': 'uint256[]'}],
'stateMutability': 'view', 'type': 'function'}
str_0 = '0x9881fcb4'
str_1 = Helper.trans_address_n0x(web_async.toHex(1 * (10 ** token0_d)))
str_2 = '00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001'
str_3 = Helper.trans_address_n0x(token0)
str_4 = Helper.trans_address_n0x(token1)
str_5 = "0000000000000000000000000000000000000000000000000000000000000001"
data_str = str_0 + str_1 + str_2 + str_3 + str_4 + str_5
transaction = {'to': f'{Router}', 'data': data_str}
function = await Helper.get_functions_(fn_abi, transaction, web_async)
# print("token amount", function)
return function
@staticmethod
async def get_amounts_out(token0, token1, web_async, Router, token0_d):
"""
get price rate
:param token0:
:param token1:
:param web_async:
:param Router:
:param token0_d:
:return:
"""
fn_abi = {'inputs': [{'internalType': 'uint256', 'name': 'amountIn', 'type': 'uint256'},
{'internalType': 'address[]', 'name': 'path', 'type': 'address[]'}],
'name': 'getAmountsOut',
'outputs': [{'internalType': 'uint256[]', 'name': 'amounts', 'type': 'uint256[]'}],
'stateMutability': 'view', 'type': 'function'}
str_0 = '0xd06ca61f'
str_1 = Helper.trans_address_n0x(web_async.toHex(1 * (10 ** token0_d)))
str_2 = '00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002'
str_3 = Helper.trans_address_n0x(token0)
str_4 = Helper.trans_address_n0x(token1)
data_str = str_0 + str_1 + str_2 + str_3 + str_4
transaction = {'to': f'{Router}', 'data': data_str}
function = await Helper.get_functions_(fn_abi, transaction, web_async)
# print("token amount", function)
return function
@staticmethod
async def get_token_detail_web(token, chain):
"""
get goPlus token detail
:param token:
:param chain:
:return:
"""
url = f'https://api.gopluslabs.io/api/v1/token_security/{chain}?contract_addresses={token}'
async with aiohttp.ClientSession() as session:
proxy = Helper.aiohttp_proxy_pool()
headers = Helper.getHeaders()
res = await session.get(url, headers=headers, proxy=proxy, timeout=10)
res = await res.text()
da = json.loads(res)
return da['result'][token.lower()] if token.lower() in da['result'] else {}
@staticmethod
async def get_sell_radio(token, sell_num, token_d, address, web_async):
"""
get sell radio
:param token:
:param sell_num:
:param token_d:
:param address:
:param web_async:
:return:
"""
if address is not None:
balance = await Helper.get_token_balance(token, address, web_async)
balance = balance / (10 ** token_d)
sell_radio = sell_num / (sell_num + balance)
return {
'radio': sell_radio,
'balance': balance,
}
else:
return {
'radio': None,
'balance': None,
}
@staticmethod
async def balancer_sell_radio(token, token_d, tx_hash, token_a, sell_num, web_async):
"""
balancer sell info
:param token:
:param token_d:
:param tx_hash:
:param token_a:
:param sell_num:
:param web_async:
:return:
"""
tran_str = Helper.tran_str()
pool = "0x000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8"
receipt = await web_async.eth.get_transaction_receipt(tx_hash)
logs = receipt['logs']
address = None
for log in logs:
if log['address'] == token and log['topics'][0].hex() == tran_str and log['topics'][
2].hex() == pool and eval(log['data']) == token_a:
address = log['topics'][1].hex()
address = web_async.toChecksumAddress(Helper.hex2bsc(address))
break
else:
pass
sell_radio, balance = None, None
if address is not None:
balance = await Helper.get_token_balance(token, address, web_async)
balance = balance / (10 ** token_d)
sell_radio = sell_num / (sell_num + balance)
return {
'address': address,
'radio': sell_radio,
'balance': balance
}
@staticmethod
async def Beethoven_sell_radio(token, token_d, tx_hash, token_a, sell_num, web_async):
"""
beethoven sell info
:param token:
:param token_d:
:param tx_hash:
:param token_a:
:param sell_num:
:param web_async:
:return:
"""
tran_str = Helper.tran_str()
pool = "0x00000000000000000000000020dd72ed959b6147912c2e529f0a0c651c33c9ce"
receipt = await web_async.eth.get_transaction_receipt(tx_hash)
logs = receipt['logs']
address = None
for log in logs:
if log['address'] == token and log['topics'][0].hex() == tran_str and log['topics'][
2].hex() == pool and eval(log['data']) == token_a:
address = log['topics'][1].hex()
address = web_async.toChecksumAddress(Helper.hex2bsc(address))
break
else:
pass
sell_radio, balance = None, None
if address is not None:
balance = await Helper.get_token_balance(token, address, web_async)
balance = balance / (10 ** token_d)
sell_radio = sell_num / (sell_num + balance)
return {
'address': address,
'radio': sell_radio,
'balance': balance
}
@staticmethod
async def get_new_holder(token, token_d, address, buy_num, web_async):
"""
get new holder info
:param token:
:param token_d:
:param address:
:param buy_num:
:param web_async:
:return:
"""
address = web_async.toChecksumAddress(address)
balance = await Helper.get_token_balance(token, address, web_async)
balance = balance / (10 ** token_d)
if balance <= buy_num:
new = 1
else:
new = 0
return {
'balance': balance,
'new': new
}
@staticmethod
async def balancer_new_holder(token, tx_hash, token_a, web_async):
"""
balancer new holder info
:param token:
:param tx_hash:
:param token_a:
:param web_async:
:return:
"""
tran_str = Helper.tran_str()
pool = "0x000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8"
receipt = await web_async.eth.get_transaction_receipt(tx_hash)
logs = receipt['logs']
address = None
for log in logs:
if log['address'] == token and log['topics'][0].hex() == tran_str and log['topics'][
1].hex() == pool and eval(log['data']) == token_a:
address = log['topics'][2].hex()
address = web_async.toChecksumAddress(Helper.hex2bsc(address))
break
else:
pass
# print('address', address)
new, balance = 0, 0
if address is not None:
balance = await Helper.get_token_balance(token, address, web_async)
if balance == token_a:
new = 1
return {
'balance': balance,
'address': address,
'new': new
}
@staticmethod
async def Beethoven_new_holder(token, tx_hash, token_a, web_async):
"""
beethoven new holder info
:param token:
:param tx_hash:
:param token_a:
:param web_async:
:return:
"""
tran_str = Helper.tran_str()
pool = "0x00000000000000000000000020dd72ed959b6147912c2e529f0a0c651c33c9ce"
receipt = await web_async.eth.get_transaction_receipt(tx_hash)
logs = receipt['logs']
address = None
for log in logs:
if log['address'] == token and log['topics'][0].hex() == tran_str and log['topics'][
1].hex() == pool and eval(log['data']) == token_a:
address = log['topics'][2].hex()
address = web_async.toChecksumAddress(Helper.hex2bsc(address))
break
else:
pass
# print('address', address)
new, balance = 0, 0
if address is not None:
balance = await Helper.get_token_balance(token, address, web_async)
if balance == token_a:
new = 1
return {
'balance': balance,
'address': address,
'new': new
}
@staticmethod
async def sell_address(logs, token, pool, amount, web_async):
"""
get sell address
:param logs:
:param token:
:param pool:
:param amount:
:param web_async:
:return:
"""
tran_str = Helper.tran_str()
address = None
for log in logs:
if log['address'] == token and log['topics'][0].hex() == tran_str and log['topics'][
2].hex() == pool and eval(log['data']) == amount:
address = log['topics'][1].hex()
address = web_async.toChecksumAddress(Helper.hex2bsc(address))
break
else:
pass
if address is None:
for log in logs:
if log['address'] == token and log['topics'][0].hex() == tran_str and log['topics'][2].hex() == pool:
address = log['topics'][1].hex()
address = web_async.toChecksumAddress(Helper.hex2bsc(address))
break
else:
pass
return address
@staticmethod
def hex2bsc(address):
"""
change hex-address
:param address:
:return:
"""
address = '0x' + address[26:]
return address
@staticmethod
def normalize_32_byte_hex_address(address):
"""
change type toCheckAddress
:param address:
:return:
"""
as_bytes = eth_utils.to_bytes(hexstr=address)
return eth_utils.to_normalized_address(as_bytes[-20:])
@staticmethod
def checksumAddress(address, web_async):
"""
web3 checkAddress
:param address:
:param web_async:
:return:
"""
address = Helper.normalize_32_byte_hex_address(address)
return web_async.toChecksumAddress(address)
@staticmethod
async def wBalances(amount, p_token, p_token_symbol, pDecimals, wToken, Router, redisKey, wDecimals, web_async):
"""
get wrap pool balance
:param amount
:param p_token
:param p_token_symbol
:param pDecimals
:param wToken
:param Router
:param redisKey
:param wDecimals
:param web_async
"""
redis_con = StrictRedis(connection_pool=RedisConnectionPoolSingleton())
rate = await redis_con.get(f'{redisKey}:rate:' + p_token_symbol + '-W')
opType = ['opt', 'can']
if rate is None:
if redisKey in opType:
rate = await Helper.get_amounts_out_op(p_token, wToken, web_async, Router, pDecimals)
else:
rate = await Helper.get_amounts_out(p_token, wToken, web_async, Router, pDecimals)
rate = rate[1] / (10 ** wDecimals)
await redis_con.setex(f'{redisKey}:rate:' + p_token_symbol + '-W', 60, rate)
else:
rate = json.loads(rate)
w_balances = amount * rate
return w_balances
@staticmethod
def trans_address(address):
"""
change address-hex
:param address:
:return:
"""
address = address[2:]
while len(address) < 64:
address = '0' + address
address = '0x' + address
return address.lower()
@staticmethod
async def get_pool_swap(pair, web_async):
"""
get pool swap type
:param pair:
:param web_async:
:return:
"""
status = 0
pool_swap = ''
info = await Helper.query_hash("taos:search:saved", pair)
if info is not None:
info = json.loads(info)
if "swap" in info:
pool_swap = info['swap']
status = 1
if status == 0:
try:
pool_swap = await Helper.get_token_name(pair, web_async)
except:
pool_swap = 'Error Contract'
return {
"swap": pool_swap,
"status": status
}
@staticmethod
async def pair_balance(p_token, p_token_d, pair_address, redisKey, swapType, p_amount, web_async):
"""
get pair balance
:param p_token
:param p_token_d
:param pair_address
:param redisKey
:param swapType
:param p_amount
:param web_async
"""
status = 0
balance = await Helper.query_hash(f"{redisKey}:balance", pair_address)
if balance is None:
status = 1
else:
balance = json.loads(balance)
ts_before = Helper.get_time_stamp(balance['time'])
ts = Helper.get_time_stamp(Helper.get_time())
if ts - ts_before > 300:
status = 1
else:
if swapType == "sell":
balance['p_balance'] -= p_amount
else:
balance['p_balance'] += p_amount
if balance['p_balance'] < 0:
status = 1
if status == 1:
p_token_balance = await Helper.get_token_balance(p_token, pair_address, web_async)
balance = {
'time': Helper.get_time(),
'p_balance': (p_token_balance / (10 ** p_token_d))
}
await Helper.save_hash_data(f"{redisKey}:balance", pair_address, json.dumps(balance))
return balance
@staticmethod
async def public2usd(pToken, pSymbol, usd, redisKey, Router, uDecimals, pDecimals, web_async):
"""
get public token - usd rate
:param pToken
:param pSymbol
:param usd
:param redisKey
:param Router
:param uDecimals
:param pDecimals
:param web_async
"""
busd_bsc = "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56" # BUSD (bsc)
weth_bsc = "0x2170Ed0880ac9A755fd29B2688956BD959F933F8" # ETH (bsc)
wbtc_bsc = "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c" # BTCB (bsc)
router_bsc = "0x10ED43C718714eb63d5aA57B78B54704E256024E" # pancakeSwapV2Router
redis_con = StrictRedis(connection_pool=RedisConnectionPoolSingleton())
rate = await redis_con.get(f'{redisKey}:rate:' + pSymbol + '-U')
opType = ['opt', 'can']
chainErrorRouter = ['cro', 'aur', 'gno', 'opt', 'cel', 'met', 'ast']
chainErrorToken = ['WETH', 'WBTC']
if rate is None:
if pSymbol == 'WETH' and redisKey in chainErrorRouter:
bsc_rate = await redis_con.get('bsc:rate:WETH-U')
if bsc_rate is None:
rate = await Helper.get_amounts_out(weth_bsc, busd_bsc, Helper.getWeb3Bsc(), router_bsc, 18)
uDecimals = 18
rate = rate[1] / (10 ** uDecimals)
await redis_con.setex('bsc:rate:WETH-U', 60, rate)
else:
rate = json.loads(bsc_rate)
return rate
elif pSymbol == 'WBTC' and redisKey in chainErrorRouter:
bsc_rate = await redis_con.get('bsc:rate:WBTC-U')
if bsc_rate is None:
rate = await Helper.get_amounts_out(wbtc_bsc, busd_bsc, Helper.getWeb3Bsc(), router_bsc, 18)
uDecimals = 18
rate = rate[1] / (10 ** uDecimals)
await redis_con.setex('bsc:rate:WBTC-U', 60, rate)
else:
rate = json.loads(bsc_rate)
return rate
elif redisKey in opType and pSymbol not in chainErrorToken:
rate = await Helper.get_amounts_out_op(pToken, usd, web_async, Router, pDecimals)
else:
rate = await Helper.get_amounts_out(pToken, usd, web_async, Router, pDecimals)
rate = rate[1] / (10 ** uDecimals)
await redis_con.setex(f'{redisKey}:rate:' + pSymbol + '-U', 60, rate)
else:
rate = json.loads(rate)
return rate
@staticmethod
async def redis_data(data, info, ts_, redisKey, public_token, chainId, stable, search_table, web_async):
"""
taos save insert task list
:param data:
:param info:
:param ts_:
:param redisKey:
:param public_token:
:param chainId:
:param stable:
:param search_table:
:param web_async:
:return:
"""
token = data['token']
if info is None:
try:
supply = await Helper.get_token_supply(token, web_async) / (10 ** data['token_decimals'])
symbol = await Helper.get_token_symbol(token, web_async)
name = await Helper.get_token_name(token, web_async)
except:
da = await Helper.get_token_detail_web(token, chainId)
name = da['token_name'] if "token_name" in da else ""
symbol = da['token_symbol'] if "token_symbol" in da else ""
supply = da['total_supply'] if "total_supply" in da else ""
redis_token = {
'name': name,
'symbol': symbol,
'supply': supply,
'decimals': data['token_decimals'],
'token': token
}
await Helper.save_hash_data(f'{redisKey}:tokens', token, json.dumps(redis_token))
else:
name = info['name']
symbol = info['symbol']
supply = info['supply']
basic_info = {
'name': name,
'symbol': symbol,
'supply': supply,
}
chainInfo = {
'stable': stable,
'search_table': search_table,
'chain_id': chainId,
'redis_key': redisKey
}
if chainId == 1 or chainId == 56:
token_info = dict(**data, **basic_info)
await Helper.task_list(f"{redisKey}:taos:tokens", json.dumps(token_info))
else:
token_info = dict(**data, **basic_info, **chainInfo)
await Helper.task_list("taos:insert:tokens", json.dumps(token_info))
@staticmethod
def get_swap_amount(amount):
"""
uniSwap v2 tx amount
:param amount:
:return:
"""
if amount[0:2] == "0x":
amount0In = eval('0x' + amount[2:66])
amount1In = eval('0x' + amount[66:130])
else:
amount0In = eval('0x' + amount[0:64])
amount1In = eval('0x' + amount[64:128])
amount0Out = eval('0x' + amount[-128:-64])
amount1Out = eval('0x' + amount[-64:])
swap_info = {
'0In': amount0In,
'1In': amount1In,
'0Out': amount0Out,
'1Out': amount1Out
}
return swap_info
@staticmethod
def getUniswapV3Amount(amount):
"""
uniSwap v3 tx amount
:param amount:
:return:
"""
amount0 = eval('0x' + amount[2:66])
amount1 = eval('0x' + amount[66:130])
if amount0 > amount1:
amount0 = -(uni256Max - amount0)
else:
amount1 = -(uni256Max - amount1)
swapinfo = {
"amount0": amount0,
"amount1": amount1
}
return swapinfo
@staticmethod
def getBalancerAmount(amount):
"""
balancer tx amount
:param amount:
:return:
"""
amountIn = eval('0x' + amount[2:66])
amountOut = eval('0x' + amount[66:130])
return amountIn, amountOut
@staticmethod
async def get_usd_price_V2(p_token, p_token_d, p_token_symbol, price, usd_token, uToken, redisKey, Router,
uDecimals, web_async):
"""
get usd price
:param p_token
:param p_token_d
:param p_token_symbol
:param price
:param usd_token
:param web_async
:param uToken
:param redisKey
:param Router
:param uDecimals
"""
if p_token in usd_token:
usd_price = price
else:
rate = await Helper.public2usd(p_token, p_token_symbol, uToken, redisKey, Router, uDecimals, p_token_d,
web_async)
usd_price = rate * price
return usd_price
@staticmethod
async def get_token_detail(p_token, p_token_d, p_token_symbol, pool_address, usd_token, wToken, wDecimals, uToken,
uDecimals, redisKey, Router, swapType, p_amount, web_async):
"""
get token info
:param p_token
:param p_token_d
:param p_token_symbol
:param pool_address
:param usd_token
:param wToken
:param wDecimals
:param uToken
:param uDecimals
:param redisKey
:param Router
:param swapType
:param p_amount
:param web_async
"""
balance = await Helper.pair_balance(p_token, p_token_d, pool_address, redisKey, swapType, p_amount, web_async)
p_balance = balance['p_balance']
u_balance = await Helper.get_usd_price_V2(p_token, p_token_d, p_token_symbol, p_balance, usd_token, uToken,
redisKey, Router, uDecimals, web_async)
if p_token == wToken:
w_balance = p_balance
else:
w_balance = await Helper.wBalances(p_balance, p_token, p_token_symbol, p_token_d, wToken, Router, redisKey,
wDecimals, web_async)
detail = {
'pair_balance': p_balance,
'usd_balance': u_balance,
'wbnb_balance': w_balance
}
return detail
@staticmethod
async def redisSaveList(pool, dataProcess, redisKey, public_token, chainId, stable, search_table, web_async):
"""
redis task list
:param pool
:param dataProcess
:param redisKey
:param public_token
:param chainId
:param stable
:param search_table
:param web_async
"""
data = dataProcess['data']
token_detail = dataProcess['info']
ts_ = Helper.get_time_stamp(data['time'])
if 'p' in pool['r']:
pass
else:
new = await Helper.query_hash(f'{redisKey}:open:recent', data['pool_address'])
if new:
new = json.loads(new)
if 'time' in new:
ts = Helper.get_time_stamp(new['time'])
if ts_ - ts <= 86400:
data['new_token'] = 1
else:
data['new_token'] = 0
else:
data['new_token'] = 1
new['time'] = data['time']
await Helper.save_hash_data(f'{redisKey}:open:recent', data['pool_address'], json.dumps(new))
else:
data['new_token'] = 0
data['is100'] = 0
holder_info = await Helper.query_hash(f'{redisKey}:holder:100', data['token'])
data_ = {
'chain': redisKey,
'token': data['token']
}
if holder_info is not None:
holder_info = json.loads(holder_info)
holder_list = holder_info['holder_100']
time_ = holder_info['date']
stamp = Helper.get_time_stamp(time_)
if ts_ - stamp <= 3600:
if (data['swap_address']).lower() in holder_list:
data['is100'] = 1
else:
await Helper.task_list('chain:holderQueue', json.dumps(data_))
else:
await Helper.task_list('chain:holderQueue', json.dumps(data_))
await Helper.redis_data(data, token_detail, ts_, redisKey, public_token, chainId, stable, search_table,
web_async)
@staticmethod
def get_time():
"""
get millisecond time
:return:
"""
ct = time.time()
local_time = time.localtime(ct)
data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
data_secs = (ct - np.compat.long(ct)) * 1000
time_stamp = "%s.%03d" % (data_head, data_secs)
return time_stamp
@staticmethod
def get_time_add(s):
"""
recent time add millisecond time
:param s:
:return:
"""
ct = (Helper.get_stamp(Helper.get_time()) + s) / 1000
local_time = time.localtime(ct)
data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
data_secs = (ct - np.compat.long(ct)) * 1000
time_stamp = "%s.%03d" % (data_head, data_secs)
return time_stamp
@staticmethod
def get_time_add_old(ts, s):
"""
ts add millisecond time
:param ts:
:param s:
:return:
"""
ct = (int(ts) + s) / 1000
local_time = time.localtime(ct)
data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
data_secs = (ct - np.compat.long(ct)) * 1000
time_stamp = "%s.%03d" % (data_head, data_secs)
return time_stamp
@staticmethod
def get_stamp(timeStr):
"""
get millisecond timestamp
:param timeStr:
:return:
"""
try:
datetime_obj = datetime.datetime.strptime(timeStr, "%Y-%m-%d %H:%M:%S.%f")
except ValueError:
datetime_obj = datetime.datetime.strptime(timeStr, "%Y-%m-%d %H:%M:%S")
obj_stamp = int(time.mktime(datetime_obj.timetuple()) * 1000.0 + datetime_obj.microsecond / 1000.0)
return obj_stamp
@staticmethod
def get_time_stamp(date):
"""
get seconds timestamp
:param date:
:return:
"""
try:
d = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f")
except:
d = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
t = d.timetuple()
time_stamp = int(time.mktime(t))
return time_stamp
@staticmethod
def get_all_proxy():
"""
get rola all type proxy
:return:
"""
proxies_address = requests.get(
'http://list.rola.info:8088/user_get_ip_list?token=JyJu6trbF4LguQxA1656402892061&type=datacenter&qty=1&time=5&country=&format=txt&protocol=http&filter=1').text
async_proxy = f"http://{proxies_address}"
proxy = {
'https': f"http://{proxies_address}",
'http': f"http://{proxies_address}",
}
return {
"proxy": proxy,
"async_proxy": async_proxy
}
@staticmethod
def all_proxy_pool():
"""
get random all type proxy
:return:
"""
proxy_lst = Helper.getProxyList()
index = random.randint(0, 999)
proxies_address = proxy_lst[index]
async_proxy = f"http://{proxies_address}"
proxy = {
'https': f"http://{proxies_address}",
'http': f"http://{proxies_address}",
}
return {
"proxy": proxy,
"async_proxy": async_proxy
}
@staticmethod
def aiohttp_proxy_pool():
"""
get aiohttp proxy
:return:
"""
proxy_lst = Helper.getProxyList()
index = random.randint(0, 999)
proxy = proxy_lst[index]
proxies = f"http://{proxy}"
return proxies
@staticmethod
def requests_proxy_pool():
"""
get http proxy
:return:
"""
proxy_lst = Helper.getProxyList()
index = random.randint(0, 999)
proxy = proxy_lst[index]
proxies = {
'https': f"http://{proxy}",
'http': f"http://{proxy}",
}
return proxies
@staticmethod
def get_radio(radio):
"""
get radio
:param radio:
:return:
"""
fen = "%.2f%%" % (radio * 100)
return fen
@staticmethod
def getHeaders():
"""
get http headers
:return:
"""
ua = UserAgent()
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-language': 'zh-CN,zh;q=0.9',
'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'iframe',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'same-origin',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': ua.chrome
}
return headers
@staticmethod
async def request_page(url, proxy):
"""
aiohttp get page
:param url:
:param proxy:
:return:
"""
# headers = Helper.getHeaders()
async with aiohttp.ClientSession() as session:
# response = await session.get(url, headers=headers, proxy=proxy, timeout=20)
response = await session.get(url, proxy=proxy, timeout=20)
return await response.text()
@staticmethod
async def getTroops(chain, token):
"""
get bsc/eth troops info
:param chain:
:param token:
:return:
"""
if chain == 56:
url = f'https://aywt3wreda.execute-api.eu-west-1.amazonaws.com/default/IsHoneypot?chain=bsc2&token={token}'
else:
url = f'https://aywt3wreda.execute-api.eu-west-1.amazonaws.com/default/IsHoneypot?chain=eth&token={token}'
troops = dict()
for i in range(5):
try:
proxy = Helper.aiohttp_proxy_pool()
res = await Helper.request_page(url, proxy)
troops = json.loads(res)
break
except Exception as e:
print("get troops error!", e)
return troops
@staticmethod
async def getHolderNum(chain, token):
"""
get holder nums
:param chain:
:param token:
:return:
"""
if chain == 56:
url = f"https://bscscan.com/token/generic-tokenholders2?m=normal&a={token}&s=8000000000000&sid=&p=1"
else:
url = f"https://cn.etherscan.com/token/generic-tokenholders2?m=normal&a={token}&s=888888888000000000&sid=&p=1"
holder_num = 0
for i in range(5):
try:
proxy = Helper.aiohttp_proxy_pool()
res = await Helper.request_page(url, proxy)
html = etree.HTML(res)
holder_list = html.xpath('//*[@class="mb-2 mb-md-0"]/text()')[0].strip()
holder_num = re.findall(r"\d+,?\d*", holder_list)[0]
# 代币持仓人数
holder_num = int(holder_num.replace(',', ''))
break
except Exception as e:
print("get holder nums error!", e)
return holder_num
@staticmethod
def getWeb3Bsc():
"""
async bsc web3
:return:
"""
bsc = "https://rpc.ankr.com/bsc"
# proxy = Helper.aiohttp_proxy_pool()
# request_kwargs={"proxy": proxy}
web_async = Web3(Web3.AsyncHTTPProvider(bsc), modules={'eth': (AsyncEth,)},
middlewares=[])
return web_async
@staticmethod
def getWeb3Eth():
"""
async eth web3
:return:
"""
eth = "https://rpc.ankr.com/eth"
proxy = Helper.aiohttp_proxy_pool()
web_async = Web3(Web3.AsyncHTTPProvider(eth, request_kwargs={"proxy": proxy}), modules={'eth': (AsyncEth,)},
middlewares=[])
return web_async
@staticmethod
def bscPoolType(token):
"""
bsc public token
:param token:
:return:
"""
if token == 'WBNB':
return '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'
elif token == 'BUSD':
return '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56'
elif token == 'USDT':
return '0x55d398326f99059fF775485246999027B3197955'
elif token == 'USDC':
return '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d'
elif token == 'BTCB':
return '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c'
elif token == 'DAI':
return '0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3'
elif token == 'ETH':
return '0x2170Ed0880ac9A755fd29B2688956BD959F933F8'
elif token == 'FIST':
return '0xC9882dEF23bc42D53895b8361D0b1EDC7570Bc6A'
elif token == 'DOGE':
return '0xbA2aE424d960c26247Dd6c32edC70B295c744C43'
elif token == 'Cake':
return '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82'
@staticmethod
def bscPoolDecimal(token):
"""
bsc pool decimals
:param token:
:return:
"""
if token == 'WBNB':
return 18
elif token == 'BUSD':
return 18
elif token == 'USDT':
return 18
elif token == 'USDC':
return 18
elif token == 'BTCB':
return 18
elif token == 'DAI':
return 18
elif token == 'ETH':
return 18
elif token == 'FIST':
return 6
elif token == 'DOGE':
return 8
elif token == 'Cake':
return 18
@staticmethod
def ethPoolType(token):
"""
eth public token
:param token:
:return:
"""
if token == 'WETH':
return '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
elif token == 'USDT':
return '0xdAC17F958D2ee523a2206206994597C13D831ec7'
elif token == 'USDC':
return '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
elif token == 'BUSD':
return '0x4Fabb145d64652a948d72533023f6E7A623C7C53'
elif token == 'WBTC':
return '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599'
elif token == 'DAI':
return '0x6B175474E89094C44Da98b954EedeAC495271d0F'
elif token == 'BNB':
return '0xB8c77482e45F1F44dE1745F52C74426C631bDD52'
@staticmethod
def ethPoolDecimal(token):
"""
eth pool decimals
:param token:
:return:
"""
if token == 'WETH':
return 18
elif token == 'USDT':
return 6
elif token == 'USDC':
return 6
elif token == 'BUSD':
return 18
elif token == 'WBTC':
return 8
elif token == 'DAI':
return 18
elif token == 'BNB':
return 18
if __name__ == '__main__':
# a = Helper.updateProxyLst()
# if a[0] == 0:
# print("代理未过期!")
# else:
# proxyLst = a[1]
# print(proxyLst)
print(Helper.getProxyLst())
......@@ -7,7 +7,7 @@ import requests
import re
import openai
from loguru import logger
from Helper import RedisCon, Helper
from Helper import RedisCon
# key
api_key = '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'
......
......@@ -70,24 +70,19 @@ async def main():
page = cur_pages[0]
await page.goto('https://discord.com/channels/@me')
await login(page)
time.sleep(20)
# 测试文字
test_title = '你好你好你好222'
# 插入文本
input_path = '//*[@id="app-mount"]/div[2]/div[1]/div[1]/div/div[2]/div/div/div/div/div[2]/div/main/form/div/div[2]/div/div[2]/div/div/div/span[2]/span[2]/span/span/span'
element = await FindElement(page, input_path)
# var evt = new InputEvent('input', {
# inputType: 'insertText',
# data: st,
# dataTransfer: null,
# isComposing: false
# });
# dom.dispatchEvent(evt);
if element:
await page.evaluate('''(element,test_title) => {
element.innerHTML = test_title
var dom = document.querySelector('body')
console.log(dom)
dom.value = test_title
const ke = new KeyboardEvent('keydown', {
bubbles: true, cancelable: true, keyCode: 49
});
document.body.dispatchEvent(ke);
}''', element, test_title)
logger.info('成功')
# 回车
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment