Commit bec065dd by lei

1

parent ae8c6e36
import re
import time import time
import json import json
import redis import redis
import random import random
import aiohttp import aiohttp
import requests import requests
from web3 import Web3
from web3.eth import AsyncEth
import datetime import datetime
import itertools
import eth_utils
import numpy as np import numpy as np
from lxml import etree
from fake_useragent import UserAgent
from aredis import StrictRedis, ConnectionPool 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 uni256Max = 2 ** 256
...@@ -366,32 +357,6 @@ class Helper: ...@@ -366,32 +357,6 @@ class Helper:
print("Redis setex error", e) print("Redis setex error", e)
@staticmethod @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): async def get_token_decimals(token, web_async):
""" """
web3 decimals web3 decimals
...@@ -547,450 +512,6 @@ class Helper: ...@@ -547,450 +512,6 @@ class Helper:
return function return function
@staticmethod @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): async def redis_data(data, info, ts_, redisKey, public_token, chainId, stable, search_table, web_async):
""" """
taos save insert task list taos save insert task list
...@@ -1104,68 +625,6 @@ class Helper: ...@@ -1104,68 +625,6 @@ class Helper:
return amountIn, amountOut return amountIn, amountOut
@staticmethod @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): async def redisSaveList(pool, dataProcess, redisKey, public_token, chainId, stable, search_table, web_async):
""" """
redis task list redis task list
...@@ -1439,61 +898,6 @@ class Helper: ...@@ -1439,61 +898,6 @@ class Helper:
return troops return troops
@staticmethod @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): def bscPoolType(token):
""" """
bsc public token bsc public token
......
...@@ -70,24 +70,19 @@ async def main(): ...@@ -70,24 +70,19 @@ async def main():
page = cur_pages[0] page = cur_pages[0]
await page.goto('https://discord.com/channels/@me') await page.goto('https://discord.com/channels/@me')
await login(page) await login(page)
time.sleep(20)
# 测试文字 # 测试文字
test_title = '你好你好你好222' 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' 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) element = await FindElement(page, input_path)
# var evt = new InputEvent('input', {
# inputType: 'insertText',
# data: st,
# dataTransfer: null,
# isComposing: false
# });
# dom.dispatchEvent(evt);
if element: if element:
await page.evaluate('''(element,test_title) => { await page.evaluate('''(element,test_title) => {
element.innerHTML = test_title element.innerHTML = test_title
var dom = document.querySelector('body') const ke = new KeyboardEvent('keydown', {
console.log(dom) bubbles: true, cancelable: true, keyCode: 49
dom.value = test_title });
document.body.dispatchEvent(ke);
}''', element, test_title) }''', element, test_title)
logger.info('成功') 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