Commit bec065dd by lei

1

parent ae8c6e36
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
......@@ -366,32 +357,6 @@ class Helper:
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
......@@ -547,450 +512,6 @@ class Helper:
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
......@@ -1104,68 +625,6 @@ class Helper:
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
......@@ -1439,61 +898,6 @@ class Helper:
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
......
......@@ -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