Как запускать файлы .py и .ipynb написано в инструкции.
Скачайте репозиторий с Гитхаба. В нем будет 4 скрипта:
API_KEY = '8gb2d2f2-274b-455d-967e-9fdcb490f46c'
SECRET_KEY = 'D27A0AA2C55BC18B15055580921E56209'
PASSPHRASE = 'secret_phrase'
Документация: https://www.okx.com/docs-v5/en/?python#overview-rest-authentication
Код взят отсюда: https://stackoverflow.com/questions/66486374/how-to-sign-an-okex-api-request
import requests
import json
import datetime
import hmac
import base64
OKX_DOMAIN = 'https://www.okx.com'
ENDPOINT = '/api/v5/asset/balances'
def get_time():
now = datetime.datetime.utcnow()
timestamp = now.isoformat("T", "milliseconds")
return timestamp + "Z"
def signature(timestamp, method, endpoint, body, secret_key):
if str(body) == '{}' or str(body) == 'None':
body = ''
message = str(timestamp) + str.upper(method) + endpoint + str(body)
mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
d = mac.digest()
return base64.b64encode(d)
def get_header():
body= {}
method= 'GET'
header = dict()
header['CONTENT-TYPE'] = 'application/json'
header['OK-ACCESS-KEY'] = API_KEY
header['OK-ACCESS-SIGN'] = signature(get_time(), method, ENDPOINT, body, SECRET_KEY)
header['OK-ACCESS-TIMESTAMP'] = str(get_time())
header['OK-ACCESS-PASSPHRASE'] = PASSPHRASE
return header
url = OKX_DOMAIN + ENDPOINT
header = get_header()
response= requests.get(url, headers=header)
result = response.json()
ENDPOINT = '/api/v5/asset/balances?ccy=USDC'
url = OKX_DOMAIN + ENDPOINT
header = get_header()
response= requests.get(url, headers=header)
result = response.json()
Okx предлагает библиотеку https://pypi.org/project/python-okx/, которая сокращает количество кода и делает работу немного удобнее.
С помощью библиотеки okx выполним аналогичную задачу, которая выше решалась с помощью requests.
import okx.Funding as Funding
funding_api = Funding.FundingAPI(API_KEY, SECRET_KEY, PASSPHRASE, False, '0')
result = funding_api.get_balances()
result = funding_api.get_balances('USDC')import pandas as pd
import okx.Funding as Funding
API_KEY = '8gb2d2f2-274b-455d-967e-9fdcb490f46c'
SECRET_KEY = 'D27A0AA2C55BC18B15055580921E56209'
PASSPHRASE = 'secret_phrase'
fundingAPI = Funding.FundingAPI(API_KEY, SECRET_KEY, PASSPHRASE, False, '0')
Получение информации об ассетах.
Документация https://www.okx.com/docs-v5/en/?python#funding-account-rest-api-get-currencies
result = fundingAPI.get_currencies()
list_of_dicts = []
for element in range(len(result['data'])):
dictionary = dict()
dictionary['asset_name'] = result['data'][element]['ccy']
dictionary['chain_name'] = result['data'][element]['chain']
dictionary['min_fee'] = result['data'][element]['minFee']
dictionary['max_fee'] = result['data'][element]['maxFee']
list_of_dicts.append(dictionary)
df = pd.DataFrame.from_dict(list_of_dicts)
writer_kernel = pd.ExcelWriter('assets_settings.xlsx', engine='xlsxwriter')
df.to_excel(writer_kernel, index=False)
writer_kernel.close()import random
import time
import pandas as pd
import okx.Funding as Funding
API_KEY = '8gb2d2f2-274b-455d-967e-9fdcb490f46c'
SECRET_KEY = 'D27A0AA2C55BC18B15055580921E56209'
PASSPHRASE = 'secret_phrase'
SETTINGS_XLSX = 'wallet_addresses_var_1.xlsx'
SETTINGS_TXT = 'wallet_addresses_var_1.txt'
ASSET_NAME = 'USDC'
CHAIN_NAME = 'USDC-Arbitrum One (Bridged)'
FEE = 0.1
TOTAL_SENDING_AMOUNT = 50
Стоит попытаться немного уникализировать тразакции, можно повлиять на отправляемую сумму и время - задержку между отправками.
Для задержки между транзакциями нужно задать минимальное время задержки и максимальное. Из диапазона этих значений будет выбираться случайное число.
MIN_TIMESLEEP_BETWEEN_TRANSACTIONS = 240
MAX_TIMESLEEP_BETWEEN_TRANSACTIONS = 480
MIN_VALUE_IN_RANGE_DIVIDER = 10000
MAX_VALUE_IN_RANGE_DIVIDER = 100
WALLETS_QUANTITY = 10
Например, я собираюсь разбросать по 10 кошелькам (WALLETS_QUANTITY) 50 USDC (TOTAL_SENDING_AMOUNT).
Отправляемое количество крипты для каждого кошелька будет определяться так:
общая сумма для всех кошельков делится на количество кошельков, вычитается комиссия, вычитается случайное число.
TOTAL_SENDING_AMOUNT / WALLETS_QUANTITY - FEE - random.uniform(TOTAL_SENDING_AMOUNT / MIN_VALUE_IN_RANGE_DIVIDER,
TOTAL_SENDING_AMOUNT / MAX_VALUE_IN_RANGE_DIVIDER)
total = []
for number in range(10):
sent_amount = TOTAL_SENDING_AMOUNT / WALLETS_QUANTITY - FEE - random.uniform(
TOTAL_SENDING_AMOUNT / MIN_VALUE_IN_RANGE_DIVIDER,
TOTAL_SENDING_AMOUNT / MAX_VALUE_IN_RANGE_DIVIDER
)
print('Wallet №:', number, 'sent:', sent_amount)
total.append(sent_amount)
REPORT_NAME = 'report_table_var_1.xlsx'
Дополнительно напишу функцию, которая будет создавать отчет и сохраняться его в xlsx. В нем будет записан адрес кошелька, отправленная сумма, поле с кодом и расшифровкой ошибки, если транзакция будет отклонена.
excel_export записывает данные в excel. Принимает таблицу с данными (датафрейм) и название будущего отчета:
def excel_export(table, table_name):
writer_kernel = pd.ExcelWriter(table_name, engine='xlsxwriter')
table.to_excel(writer_kernel, index=False)
writer_kernel.close()
def open_table():
try:
table = pd.read_excel(REPORT_NAME)
return table.to_dict('records')
except:
table_template = pd.DataFrame(index=[0])
excel_export(table_template, REPORT_NAME)
created_table = pd.read_excel(REPORT_NAME)
return created_table.to_dict('records')
def create_report(report_table, address, asset_name, chain, sent_amount, error):
report_dict = dict()
report_dict['address'] = address
report_dict['asset_name'] = asset_name
report_dict['chain'] = chain
report_dict['sent_amount'] = sent_amount
report_dict['error'] = error
report_table.append(report_dict)
result_table = pd.DataFrame.from_dict(report_table)
result_table.dropna(inplace=True)
excel_export(result_table, REPORT_NAME)
wallet_addresses_xlsx = pd.read_excel(SETTINGS_XLSX)
wallet_addresses_list = wallet_addresses_xlsx['address'].to_list()
with open(SETTINGS_TXT, 'r') as f:
data = f.readlines()
wallet_addresses_list = [adress.replace('\n', '') for adress in data]
fundingAPI = Funding.FundingAPI(API_KEY, SECRET_KEY, PASSPHRASE, False, '0')
Документация отправки активов с биржи https://www.okx.com/docs-v5/en/?python#funding-account-rest-api-withdrawal
for address in wallet_addresses_list:
try:
sending_amount = (TOTAL_SENDING_AMOUNT / len(wallet_addresses_list) -
FEE -
random.uniform(TOTAL_SENDING_AMOUNT / MIN_VALUE_IN_RANGE_DIVIDER,
TOTAL_SENDING_AMOUNT / MAX_VALUE_IN_RANGE_DIVIDER))
print(f'Sending {sending_amount} {ASSET_NAME} to address {address} in chain {CHAIN_NAME}')
api_response = fundingAPI.withdrawal(
ccy=ASSET_NAME,
toAddr=address,
amt=sending_amount,
fee=FEE,
dest="4",
chain=CHAIN_NAME
)
if api_response['code'] == '0':
print('Sent')
print('Creating report', '\n')
report_table = open_table()
create_report(report_table, address, ASSET_NAME, CHAIN_NAME, sending_amount, '-')
elif api_response['code'] != '0':
print('Didnt send')
print('Creating report', '\n')
error_code = api_response['code']
error_message = api_response['msg']
error_report_string = f'{error_code}-{error_message}'
report_table = open_table()
create_report(report_table, address, ASSET_NAME, CHAIN_NAME, sending_amount, error_report_string)
time_sleep_value = random.choice(range(MIN_TIMESLEEP_BETWEEN_TRANSACTIONS,
MAX_TIMESLEEP_BETWEEN_TRANSACTIONS))
print('Delay', time_sleep_value, '\n')
time.sleep(time_sleep_value)
except Exception as error:
print('Didnt send')
print('Creating report', '\n')
report_table = open_table()
create_report(report_table, '-', '-', '-', '-', error)
import random
import time
import pandas as pd
import okx.Funding as Funding
API_KEY = '8gb2d2f2-274b-455d-967e-9fdcb490f46c'
SECRET_KEY = 'D27A0AA2C55BC18B15055580921E56209'
PASSPHRASE = 'secret_phrase'
SETTINGS_XLSX = 'sending_settings_var_2.xlsx'
SETTINGS_TXT = 'sending_settings_var_2.txt'
MIN_TIMESLEEP_BETWEEN_TRANSACTIONS = 240
MAX_TIMESLEEP_BETWEEN_TRANSACTIONS = 480
REPORT_NAME = 'report_table_var_2.xlsx'
Такие же функции для создания отчета, которые использовались в первом примере скрипта.
excel_export записывает данные в excel. Принивает таблицу с данными (датафрейм), название будущего отчета:
def excel_export(table, table_name):
writer_kernel = pd.ExcelWriter(table_name, engine='xlsxwriter')
table.to_excel(writer_kernel, index=False)
writer_kernel.close()
def open_table():
try:
table = pd.read_excel(REPORT_NAME)
return table.to_dict('records')
except:
table_template = pd.DataFrame(index=[0])
excel_export(table_template, REPORT_NAME)
created_table = pd.read_excel(REPORT_NAME)
return created_table.to_dict('records')
def create_report(report_table, address, asset_name, chain, sent_amount, error):
report_dict = dict()
report_dict['address'] = address
report_dict['asset_name'] = asset_name
report_dict['chain'] = chain
report_dict['sent_amount'] = sent_amount
report_dict['error'] = error
report_table.append(report_dict)
result_table = pd.DataFrame.from_dict(report_table)
result_table.dropna(inplace=True)
excel_export(result_table, REPORT_NAME)
assets_settings_for_sending = pd.read_excel(SETTINGS_XLSX)
list_of_assets_settings_for_sending = assets_settings_for_sending.to_dict('records')with open(SETTINGS_TXT, 'r') as file:
lines = file.readlines()
list_of_assets_settings_for_sending = []
for line in lines:
elements = line.strip().split(';')
wallet_address, asset_name, amount, fee, chain_name = elements[0].split(',')
data = {
'wallet_address': wallet_address,
'asset_name': asset_name,
'amount': amount,
'fee': fee,
'chain_name': chain_name
}
list_of_assets_settings_for_sending.append(data)
fundingAPI = Funding.FundingAPI(API_KEY, SECRET_KEY, PASSPHRASE, False, '0')
for row in list_of_assets_settings_for_sending:
try:
wallet_address, asset_name, amount, fee, chain = (row['wallet_address'], row['asset_name'],
row['amount'], row['fee'], row['chain'])
print(f'Sending {amount} {asset_name} to address {wallet_address} in chain {chain}')
api_response = fundingAPI.withdrawal(
ccy=asset_name,
toAddr=wallet_address,
amt=amount - fee,
fee=fee,
dest="4",
chain=chain
)
if api_response['code'] == '0':
print('Sent')
print('Creating report', '\n')
report_table = open_table()
create_report(report_table, wallet_address, asset_name, chain, amount, '-')
elif api_response['code'] != '0':
print('Didnt send')
print('Creating report', '\n')
error_code = api_response['code']
error_message = api_response['msg']
error_report_string = f'{error_code}-{error_message}'
report_table = open_table()
create_report(report_table, wallet_address, asset_name, chain, amount, error_report_string)
time_sleep_value = random.choice(range(MIN_TIMESLEEP_BETWEEN_TRANSACTIONS,
MAX_TIMESLEEP_BETWEEN_TRANSACTIONS))
print('Delay', time_sleep_value, '\n')
time.sleep(time_sleep_value)
except Exception as error:
print('Didnt send')
print('Creating report', '\n')
report_table = open_table()
create_report(report_table, '-', '-', '-', '-', error)
Чтобы не создавать связь между кошельками, нужно отправлять крипту на саб-аккаунты. Каждый кошелек соответствует адресу на саб-аккаунте. Так завещали старшие.
Не смог найти в документации api-метода, чтобы получить адреса для депозита на саб-акках. Поэтому придется взять адреса через интерфейс биржи.
Код взят из отличной статьи https://habr.com/ru/articles/674204/
import random
import time
from web3 import Web3
import pandas as pd
SETTINGS_XLSX = 'sending_from_wallets_settings_var_1.xlsx'
SETTINGS_TXT = 'sending_from_wallets_settings_var_1.txt'
MIN_TIMESLEEP_BETWEEN_TRANSACTIONS = 240
MAX_TIMESLEEP_BETWEEN_TRANSACTIONS = 480
REPORT_NAME = 'report_table_var_sending_from_wallets_1.xlsx'
Такие же функции для создания отчета, которые использовались в первом примере скрипта.
excel_export записывает данные в excel. Принивает таблицу с данными (датафрейм), название будущего отчета:
def excel_export(table, table_name):
writer_kernel = pd.ExcelWriter(table_name, engine='xlsxwriter')
table.to_excel(writer_kernel, index=False)
writer_kernel.close()
def open_table():
try:
table = pd.read_excel(REPORT_NAME)
return table.to_dict('records')
except:
table_template = pd.DataFrame(index=[0])
excel_export(table_template, REPORT_NAME)
created_table = pd.read_excel(REPORT_NAME)
return created_table.to_dict('records')
def create_report(report_table, wallet_address, okx_address, asset_name, chain, sent_amount, txn_hash, error):
report_dict = dict()
report_dict['wallet_address'] = wallet_address
report_dict['okx_address'] = okx_address
report_dict['asset_name'] = asset_name
report_dict['chain'] = chain
report_dict['sent_amount'] = sent_amount
report_dict['txn_hash'] = txn_hash
report_dict['error'] = error
report_table.append(report_dict)
result_table = pd.DataFrame.from_dict(report_table)
result_table.dropna(inplace=True)
excel_export(result_table, REPORT_NAME)
settings_for_sending_from_wallets = pd.read_excel(SETTINGS_XLSX)
list_of_settings_for_sending_from_wallets = settings_for_sending_from_wallets.to_dict('records')with open(SETTINGS_TXT, 'r') as file:
lines = file.readlines()
list_of_assets_settings_for_sending = []
for line in lines:
elements = line.strip().split(';')
private_key, okx_sub_address, asset_name, chain_name, amount, chain_rpc = elements[0].split(',')
data = {
'private_key': private_key,
'okx_sub_address': okx_sub_address,
'asset_name': asset_name,
'chain_name': chain_name,
'amount': amount,
'chain_rpc': chain_rpc
}
list_of_assets_settings_for_sending.append(data)
for row in list_of_settings_for_sending_from_wallets:
try:
private_key, okx_sub_address, asset_name, chain_name, amount, chain_rpc = (row['private_key'],
row['okx_sub_address'],
row['asset_name'],
row['chain_name'],
row['amount'],
row['chain_rpc'])
web3 = Web3(Web3.HTTPProvider(chain_rpc))
from_address = web3.eth.account.from_key(private_key).address
print(f'Sending {amount} {asset_name} on the {chain_name} network from address {from_address}')
to_address = web3.to_checksum_address(okx_sub_address)
print(f'To OKX address {to_address}')
amount_wei = int(web3.to_wei(amount, 'ether'))
gas_price = web3.eth.gas_price
estimated_gas = web3.eth.estimate_gas({
'to': to_address,
'value': amount_wei,
})
fee = gas_price * estimated_gas
nonce = web3.eth.get_transaction_count(from_address)
transaction_settings = {
'chainId': web3.eth.chain_id,
'from': from_address,
'to': to_address,
'value': amount_wei - fee,
'nonce': nonce,
'gasPrice': gas_price,
'gas': estimated_gas,
}
sent_amount = float(web3.from_wei(amount_wei - fee, 'ether'))
signed_transaction = web3.eth.account.sign_transaction(transaction_settings, private_key)
transaction_hash = web3.eth.send_raw_transaction(signed_transaction.rawTransaction)
print('Sent')
print('Txn hash:', transaction_hash.hex())
print('Creating report')
report_table = open_table()
create_report(report_table, from_address, to_address,
asset_name, chain_name, sent_amount, transaction_hash.hex(), '-')
time_sleep_value = random.choice(range(MIN_TIMESLEEP_BETWEEN_TRANSACTIONS,
MAX_TIMESLEEP_BETWEEN_TRANSACTIONS))
print('Delay', time_sleep_value, '\n')
time.sleep(time_sleep_value)
except Exception as error:
print('Didnt send')
print('Creating report')
report_table = open_table()
create_report(report_table, from_address, to_address,
asset_name, chain_name, '-', '-', error)
import random
import json
import time
from web3 import Web3
import pandas as pd
JSON_NAME = 'ERC20_ABI.json'
SETTINGS_XLSX = 'sending_from_wallets_settings_var_2.xlsx'
SETTINGS_TXT = 'sending_from_wallets_settings_var_2.txt'
MIN_TIMESLEEP_BETWEEN_TRANSACTIONS = 240
MAX_TIMESLEEP_BETWEEN_TRANSACTIONS = 480
REPORT_NAME = 'report_table_var_sending_from_wallets_2.xlsx'
Такие же функции для создания отчета, которые использовались в первом примере скрипта.
excel_export записывает данные в excel. Принимает таблицу с данными (датафрейм), название будущего отчета:
def excel_export(table, table_name):
writer_kernel = pd.ExcelWriter(table_name, engine='xlsxwriter')
table.to_excel(writer_kernel, index=False)
writer_kernel.close()
def open_table():
try:
table = pd.read_excel(REPORT_NAME)
return table.to_dict('records')
except:
table_template = pd.DataFrame(index=[0])
excel_export(table_template, REPORT_NAME)
created_table = pd.read_excel(REPORT_NAME)
return created_table.to_dict('records')
def create_report(report_table, wallet_address, okx_address, asset_name, chain, sent_amount, txn_hash, error):
report_dict = dict()
report_dict['wallet_address'] = wallet_address
report_dict['okx_address'] = okx_address
report_dict['asset_name'] = asset_name
report_dict['chain'] = chain
report_dict['sent_amount'] = sent_amount
report_dict['txn_hash'] = txn_hash
report_dict['error'] = error
report_table.append(report_dict)
result_table = pd.DataFrame.from_dict(report_table)
result_table.dropna(inplace=True)
excel_export(result_table, REPORT_NAME)
settings_for_sending_from_wallets = pd.read_excel(SETTINGS_XLSX)
list_of_settings_for_sending_from_wallets = settings_for_sending_from_wallets.to_dict('records')with open(SETTINGS_TXT, 'r') as file:
lines = file.readlines()
list_of_assets_settings_for_sending = []
for line in lines:
elements = line.strip().split(';')
private_key, okx_sub_address, asset_name, chain_name, token_contract, amount, chain_rpc = elements[0].split(',')
data = {
'private_key': private_key,
'okx_sub_address': okx_sub_address,
'asset_name': asset_name,
'chain_name': chain_name,
'token_contract': token_contract,
'amount': amount,
'chain_rpc': chain_rpc
}
list_of_assets_settings_for_sending.append(data)
with open(JSON_NAME, 'r') as file:
abi_json = json.load(file)
for row in list_of_settings_for_sending_from_wallets:
try:
private_key, okx_sub_address, asset_name, chain_name, contract, amount, chain_rpc = (row['private_key'],
row['okx_sub_address'],
row['asset_name'],
row['chain_name'],
row['token_contract'],
row['amount'],
row['chain_rpc'])
web3 = Web3(Web3.HTTPProvider(chain_rpc))
from_address = web3.eth.account.from_key(private_key).address
print(f'Sending {amount} {asset_name} on the {chain_name} network from address {from_address}')
to_address = web3.to_checksum_address(okx_sub_address)
print(f'To OKX address {to_address}')
token_contract = web3.eth.contract(web3.to_checksum_address(contract), abi=abi_json)
token_decimals = token_contract.functions.decimals().call()
sending_amount = int(amount * 10**token_decimals)
transaction_settings = {
'chainId': web3.eth.chain_id,
'from': from_address,
'gasPrice': web3.eth.gas_price,
'nonce': web3.eth.get_transaction_count(from_address)
}
transaction = token_contract.functions.transfer(to_address,
sending_amount).build_transaction(transaction_settings)
signed_transaction = web3.eth.account.sign_transaction(transaction, private_key)
transaction_hash = web3.eth.send_raw_transaction(signed_transaction.rawTransaction)
sent_amount = float(web3.from_wei(sending_amount, 'ether'))
print('Sent')
print('Txn hash:', transaction_hash.hex())
print('Creating report')
report_table = open_table()
create_report(report_table, from_address, to_address,
asset_name, chain_name, sent_amount, transaction_hash.hex(), '-')
time_sleep_value = random.choice(range(MIN_TIMESLEEP_BETWEEN_TRANSACTIONS,
MAX_TIMESLEEP_BETWEEN_TRANSACTIONS))
print('Delay', time_sleep_value, '\n')
time.sleep(time_sleep_value)
except Exception as error:
print('Didnt send')
print('Creating report', '\n')
print(error, '\n')
report_table = open_table()
create_report(report_table, from_address, to_address,
asset_name, chain_name, '-', '-', error)
© Crypto-Py.com