Как проверить баланс криптокошелька python
Перейти к содержимому

Как проверить баланс криптокошелька python

  • автор:

Внедряем оплату BTC куда угодно (Python)

Полгода назад взялся за один проект с возможностью оплаты биткойном. Так как проект делали на языке python, то и оплату хотелось реализовать на нем же. Сразу же взялся анализировать готовые решения, доступные библиотеки и Rest API Blockchain.com. С апи блокчейна я моментально обломался, так как их токен для использования апи довольно не просто получить.

Затем решил юзать различные библиотеки (block-io, bitcoinlib, blockchain и др.) После пару ночей попыток реализовать нормальную оплату, остановился на bitcoinlib, так как она более менее стабильно работала, и я спокойно переводил с одного кошелька на другой. Беда наступила когда появились первые 100 пользователей и вся оплата внезапно рухнула. Возможно я криво написал или что-то не так понял с работой библиотеки, но любые попытки восстановить работу оплаты были безуспешны, только если обнулять бдшку, но и так неизвестно сколько бы она продержалась.

В итоге решили оставить без BTC оплаты. Я опечалился и не связывался с оплатой биткойном полгода.

К чему я пришел

На днях я все-таки решил добить этот вопрос для себя, надеюсь кому-то еще пригодятся мои наработки.

Все начинается с seed фразы. Мнемоническая фраза (англ. Mnemonic phrase или Seed фраза) — это список слов, которые хранят всю информацию, необходимую для восстановления биткоин-кошелька. Существуют несколько стандартов генерации фраз BIP 32, BIP 39, BIP 44, и еще BIP 49. Самый распространенный — это BIP 44 (12 слов).

Пример seed фразы:

vivid area able second bicycle advance demand alpha flip stable drift route

Чтобы сгенерировать фразу будем использовать библиотеку bipwallet. Чтобы ее установить воспользуемся командой pip install bipwallet.

from bipwallet import wallet # generate 12 word mnemonic seed seed = wallet.generate_mnemonic() print(seed)

Если мы хотим получить напрямую доступ к биткойн кошельку, то, зная фразу, можем сразу восставновить кошелек в blockhain.com:

Следующим шагом мы будем преобразовывать нашу seed фразу до получения нужного адреса кошелька биткойна.

Чтобы во всем не запутаться и знать какие данные мы должны получить, я использовал сайт https://iancoleman.io/bip39/

Генерация дочернего адреса кошелька для каждого пользователя:

Чтобы получить наш нулевой адрес Биткойн кошелька на основе seed фразы (12VeK1eRgPHRUikNLXq3Nuz99gS2S46QMD), нам нужно пройти всю цепочку преобразований. Методом проб и ошибок мне все-таки удалось получить адрес кошелька следующим кодом:

from bipwallet.utils import * def gen_address(index): # Наша seed фраза seed = 'vivid area able second bicycle advance demand alpha flip stable drift route' # Мастер ключ из seed фразы master_key = HDPrivateKey.master_key_from_mnemonic(seed) # Public key из мастер ключа по пути 'm/44/0/0/0' root_keys = HDKey.from_path(master_key, "m/44'/0'/0'/0")[-1].public_key.to_b58check() # Extended public key xpublic_key = str(root_keys, encoding="utf-8") # Адрес дочернего кошелька в зависимости от значения index address = Wallet.deserialize(xpublic_key, network='BTC').get_child(index, is_prime=False).to_address() rootkeys_wif = HDKey.from_path(master_key, f"m/44'/0'/0'/0/")[-1] # Extended private key xprivatekey = str(rootkeys_wif.to_b58check(), encoding="utf-8") # Wallet import format wif = Wallet.deserialize(xprivatekey, network='BTC').export_to_wif() return address, str(wif, 'utf-8') print(gen_address(0))

Данная функция возвращает адрес кошелька и wif в зависимости номера. Максимальное число с которым удалось получить адрес это 999999999.

wif (Wallet import format) — это просто кодирование байтов ключа в кодировку Base58 + контрольная сумма. Он нам понадобится в дальнейшем при генерации транзакции.

Это все значит, что имея только одну seed фразу мы можем создать 1 млрд дочерних адресов. Каждому пользователю при регистрации мы будем выдавать новый адрес, через который он сможет оплачивать по BTC. Появляется ограничение на 1 млрд пользователей, но нам никто не запрещает использовать несколько seed фраз или генерировать каждому юзеру новую фразу, но тогда каждая оплата будет кидаться не в общий ваш кошелек, а по разным.

Проверка баланса и транзакции:

Теперь когда у каждого пользователя свой личный адрес биткойн кошелька, нужно проверить баланс этого адреса. Для этого мы будем обращаться к сайту Blockchain.com дабы получить нужную информацию.

import requests # Адрес кошелька пользователя wallet = '12VeK1eRgPHRUikNLXq3Nuz99gS2S46QMD' # wallet = gen_address(0) url = f'https://blockchain.info/rawaddr/' x = requests.get(url) wallet = x.json() print('Итоговый баланс:'+str(wallet['final_balance'])) print('Транзакции:'+str(wallet['txs'])) if wallet['total_received']==0: print('баланс пустой') 

Вот таким простым кодом мы можем получить всю информацию по балансу и транзакциях пользователя. Дальше все зависит от логики самого приложения.

Транзакции

На данном этапе мы дали каждому пользователю свой адрес кошелька и знаем все транзакции с данным адресом, но этого недостаточно. Нам нужно чтобы мы могли отправить его же деньги обратно. Для этого воспользуемся библотекой bit. Чтобы ее установить воспользуемся командой pip install bit.

from bit import PrivateKey # Приватный ключ из wif my_key = PrivateKey(wif='L46ixenNSu8Bqk899ZrH8Y96t8DHqJ1ZyxzQBGFTbh38rLHLaPoY') # Количество долларов перевода, можно поменять на btc money=0.1 # Кошелек куда будут переведены деньги wallet='17ya3bCpPioyPH8kAyFkEDBUqdjF6wwPxo' # Коммисия перевода, если поставить слишком маленькую, то транзакцию не примут # И чем больше коммисия, тем быстрее пройдет перевод fee=2000 # Генерация транзакции tx_hash = my_key.create_transaction([(wallet, money, 'usd')],fee=fee,absolute_fee=True) print(tx_hash)

В итоге мы получили вот такую транзакцию:

Выглядит красиво, но что с этим делать?

Можно зайти на сайт https://www.blockchain.com/btc/pushtx

и вручную отправить эту транзакцию.

Также можем декодировать эту транзакцию и проверить все ли верно мы указали https://www.blockchain.com/btc/decode-tx

Но нам нужно это автоматизировать, поэтому напишем несколько строк:

import requests url = 'https://blockchain.info/pushtx' tx='0100000001fe64490fce5e85d5eb00865663a3d44f4108549fdb2840b086cfc781390d4a2d010000006a47304402202dc1496d28bb10d50d94d70870e2a79ea472c5960de8f7418bb30f9b96643efc02204691547c98edad3181a056bf6404601efe289200ba8e3073a2f5b7c0c7f4fec10121026516c551584b484ce3ca7bb71bbf24cce133bf40bdf4e2ce5a3936bc7e66a2abffffffff02e3020000000000001976a9144c83a20250ccb62ce2b3b1ea80c6082b634fdf9f88ac08f40200000000001976a9144c83a20250ccb62ce2b3b1ea80c6082b634fdf9f88ac00000000' x = requests.post(url, data = ) result = x.text print(result)

Выполним пост запрос, если получаем ответ: Transaction Submitted. Это значит, что через несколько секунд транзакция появится в сети и деньги спишутся с пользователя.

Применение

Ну чтож, написав всего несколько десятков строк, мы можем генерировать для каждого пользователя свой адрес кошелка, проверять его баланс, переводить биткойны с одного кошелька на любой другой.

Для демонстрации работы BTC оплаты, я напишу простенького телеграм бота, который будет выполнять роль клиента Blockchain.com, то есть вы сможете хранить в нем свои биткойны и от туда же переводить другим людям. Ссылка на исходники бота будут в конце.

Проверить работу бота можно тут: https://t.me/Blockchain_client_bot

Задеплоил на heroku, так что надеюсь не будет падать)

Функционал бота

Регистрация пользователя

В качестве БД я использовал sqlite3 и создал одну таблицу пользователей:

import sqlite3 conn = sqlite3.connect("my.db") # или :memory: чтобы сохранить в RAM cursor = conn.cursor() cursor.execute("CREATE TABLE users (chatid INTEGER , name TEXT, balance INTEGER, btc_wallet TEXT, wif TEXT, btc_sent TEXT, state INTEGER)") conn.commit()

При нажатии start мы регистрируем пользователя, генерируем для него адрес биткойн кошелька, wif и добавляем данные в БД:

sql = "SELECT COUNT(*) FROM users " cursor.execute(sql) user = cursor.fetchone() address, wif= gen_address(user[0]+1) sql_insert = "INSERT INTO users VALUES (<>, '<>', 0,'<>','<>','no',0)".format(message.chat.id, message.chat.first_name,address,wif) cursor.execute(sql_insert) conn.commit()

Проверка баланса

if message.text == '? Ваш баланс': url = f'https://blockchain.info/rawaddr/' x = requests.get(url) wallet = x.json() await bot.send_message(message.chat.id, f'''? *Итоговый баланс:* BTC *Всего получено:* BTC *Всего отправлено:* BTC https://www.blockchain.com/ru/btc/address/''', parse_mode= "Markdown")

Получить BTC

Для создания qr-кода я использовал библиотеку qrcode и на вход передал ранее сгенерированный адрес биткойн кошелька из БД.

 if message.text == '? Получить BTC': img = qrcode.make(data[3]) img.save('qr.jpg') await bot.send_message(message.chat.id, f'''? Ваш адрес биткойн кошелька: **''', parse_mode= "Markdown") await bot.send_photo(message.chat.id,photo=open('qr.jpg', 'rb'))

Отправить BTC

try: sum = float(message.text) url = f'https://blockchain.info/rawaddr/' x = requests.get(url) wallet = x.json() if sum + 10000 <= wallet['final_balance'] / 100000000: try: my_key = PrivateKey(wif=data[4]) # Коммисия перевода, если поставить слишком маленькую, то транзакцию не примут # И чем больше коммисия, тем быстрее пройдет перевод fee = 10000 # Генерация транзакции tx_hash = my_key.create_transaction([(data[5], sum, 'btc')], fee=fee, absolute_fee=True) print(tx_hash) url = 'https://blockchain.info/pushtx' x = requests.post(url, data=) result = x.text sql = "UPDATE users SET state = <> WHERE chatid = <>".format(0, message.chat.id) cursor.execute(sql) conn.commit() await bot.send_message(message.chat.id, result) except Exception: await bot.send_message(message.chat.id, "⚠ Ошибка при выолнении транзакции") else: await bot.send_message(message.chat.id, '⚠️ На вашем балансе недостаточно средств.') except ValueError: await bot.send_message(message.chat.id, '⚠️Неправильно введена сумма отправления, попробуйте еще раз') 

Проверим через сайт, что транзакция отправилась:

Исходники и как запустить

Скачать исходники бота можно тут: github.com/Lil-hack/blockchain-client

Склонировав репозиторий, устанавливаем необходимые пакеты:

pip install -r requirements.txt

Некоторые библиотеки у меня не заработали на windows, так что лучше сразу запускать на linux.

В файле main.py заменяем ваш токен телеграм бота:

# Ваш токен от BotFather TOKEN = 'YOUR TOKEN'

В файле btc_core.py заменяем на вашу seed фразу:

# Ваша seed фраза seed = 'YOUR SEED'

И запускаем бота командой: python main.py

Работает на python 3.7.0 и выше. Бот написан за один вечер, так что просьба строго не судить ^^

Итого

Как оказалось, все довольно не сложно, и в несколько десятков строк можно добавить оплату BTC в любой python проект. Я не профи в криптографии, так что скорее всего многие моменты упустил, но надеюсь кому-то эта статья будет полезна.

Как конвертировать публичные ключи Bitcoin-PUBKEY HEX в Bitcoin-адрес Base58 и проверить баланс на наличие монет BTC

Результат проверки Python-скрипта bitcoin-checker.py

В итоге мы с особой легкостью будем проверять баланс Биткоина, сканируя Блокчейн в терминале Google Colab [TerminalGoogleColab]

Ранее я записывал видеоинструкцию: «TERMINAL в Google Colab создаем все удобства для работ в GITHUB»

Давайте перейдем в репозиторию «CryptoDeepTools» и разберем в детали работу Bash-скрипта:getbalance.sh

Commands:

git clone https://github.com/demining/CryptoDeepTools.git cd CryptoDeepTools/03CheckBitcoinAddressBalance/ sudo apt install python2-minimal wget https://bootstrap.pypa.io/pip/2.7/get-pip.py sudo python2 get-pip.py pip3 install -r requirements.txt chmod +x getbalance.sh ./getbalance.sh 

Файлы Код нашего Bash-скрипта: getbalance.sh

grep 'PUBKEY = ' signatures.json > pubkeyall.json

Утилита grep собирает все публичные ключи в один общий файл: pubkeyall.json

sort -u pubkeyall.json > pubkey.json

Утилита sort сортирует и удаляет дубли отбирает уникальные публичные ключи и результат сохраняет в файл: pubkey.json

rm pubkeyall.json

Утилита rm удаляет pubkeyall.json

sed -i 's/PUBKEY = //g' pubkey.json

Утилита sed стирает префикс PUBKEY =

python3 pubtoaddr.py

Запускаем Python-скрипт pubtoaddr.py конвертируем из файла pubkey.json где хранятся наши публичные ключи Биткоина PUBKEY (HEX) в файл addresses.json результат сохранится как Биткойн Адреса (Base58)

import hashlib import base58 def hash160(hex_str): sha = hashlib.sha256() rip = hashlib.new('ripemd160') sha.update(hex_str) rip.update(sha.digest()) return rip.hexdigest() # .hexdigest() is hex ASCII pub_keys = open('pubkey.json', 'r', encoding='utf-8') new_file = open('addresses.json', 'a', encoding='utf-8') compress_pubkey = False for pub_key in pub_keys: pub_key = pub_key.replace('\n', '') if compress_pubkey: if (ord(bytearray.fromhex(pub_key[-2:])) % 2 == 0): pubkey_compressed = '02' else: pubkey_compressed = '03' pubkey_compressed += pub_key[2:66] hex_str = bytearray.fromhex(pubkey_compressed) else: hex_str = bytearray.fromhex(pub_key) key_hash = '00' + hash160(hex_str) sha = hashlib.sha256() sha.update(bytearray.fromhex(key_hash)) checksum = sha.digest() sha = hashlib.sha256() sha.update(checksum) checksum = sha.hexdigest()[0:8] # new_file.write("" + (base58.b58encode(bytes(bytearray.fromhex(key_hash + checksum)))).decode('utf-8')) new_file.write((base58.b58encode(bytes(bytearray.fromhex(key_hash + checksum)))).decode('utf-8') + "\n") pub_keys.close() new_file.close()

Мы получили файл addresses.json теперь проверим баланс монет Биткоина используя для этого Python-скрипт bitcoin-checker.py

Запускаем Python-скрипт: python2 bitcoin-checker.py

import sys import re from time import sleep try: # if is python3 from urllib.request import urlopen except: # if is python2 from urllib2 import urlopen def check_balance(address): #Modify the value of the variable below to False if you do not want Bell Sound when the Software finds balance. SONG_BELL = True #Add time different of 0 if you need more security on the checks WARN_WAIT_TIME = 0 blockchain_tags_json = [ 'total_received', 'final_balance', ] SATOSHIS_PER_BTC = 1e+8 check_address = address parse_address_structure = re.match(r' *([a-zA-Z1-9])', check_address) if ( parse_address_structure is not None ): check_address = parse_address_structure.group(1) else: print( "\nThis Bitcoin Address is invalid" + check_address ) exit(1) #Read info from Blockchain about the Address reading_state=1 while (reading_state): try: htmlfile = urlopen("https://blockchain.info/address/%s?format=json" % check_address, timeout = 10) htmltext = htmlfile.read().decode('utf-8') reading_state = 0 except: reading_state+=1 print( "Checking. " + str(reading_state) ) sleep(60*reading_state) print( "\nBitcoin Address :(\d+),' % tag, htmltext ).group(1) ) ) except: print( "Error '%s'." % tag ); exit(1) for i, btc_tokens in enumerate(blockchain_info_array): sys.stdout.write ("%s \t %.8f Bitcoin" % (btc_tokens/SATOSHIS_PER_BTC) ); else: print( "0 Bitcoin" ); if (SONG_BELL and blockchain_tags_json[i] == 'final_balance' and btc_tokens > 0.0): #If you have a balance greater than 0 you will hear the bell sys.stdout.write ('\a\a\a') sys.stdout.flush() arq1.write("Bitcoin Address: %s" % check_address) arq1.write("\t Balance: %.8f Bitcoin" % (btc_tokens/SATOSHIS_PER_BTC)) arq1.write("\n") arq1.close() if (WARN_WAIT_TIME > 0): sleep(WARN_WAIT_TIME) #Add the filename of your list of Bitcoin Addresses for check all. with open("addresses.json") as file: for line in file: arq1 = open('balance.json', 'a') address = str.strip(line) print ("__________________________________________________\n") check_balance(address) print "__________________________________________________\n" arq1.close()

В итоге результат сохранится в файле: balance.json

Файл: balance.json

Теперь мы научились:

  • Конвертировать публичные ключи Биткоина PUBKEY (HEX) в Биткойн Адрес (Base58)
  • Проверять все Биткойн Адреса (Base58) на наличие монет Биткоина
  • Применить это для криптоанализа

Как узнать баланс btc кошелька?

Мне нужно узнать баланс btc кошелька, зная только мнемоническую фразу.
Я так понимаю, под одной мнемонической фразой может быть множество адресов с различным балансом.
Получается нужно либо проверять все адреса ( не думаю что это хороший способ ), либо есть другой ( быстрый ) вариант.
Подскажите что нужно делать. ЯП — python.

  • Вопрос задан более года назад
  • 329 просмотров

Комментировать
Решения вопроса 0
Ответы на вопрос 2
AlbertForest @AlbertForest

Да, есть лучший вариант. Для начала гуглите что такое мнемоническая фраза. Выяснив, что множеством кошельков там и не пахнет — проверяете баланс одного единственного (или цепочки). Как получить ключ из мнемонической фразы — в гугле инфы навалом (в тч на python). Затем по приватному ключу получаете баланс с помощью bit например. Уверен, что это и есть ваш «быстрый» вариант.
Искренне надеюсь, что вас не коснулась лихорадка по поиску чужих кошельков перебором фраз. Если это так — не тратьте свое время. Это худший способ для такой (и без того безуспешной) цели

Ответ написан более года назад
Нравится 1 2 комментария

gnifajio

Gnifajio None @gnifajio Автор вопроса

Нет, я просто пытаюсь сделать какой-то мультивалютный кошелек, чтобы вводишь мнемоническую фразу, и сразу видишь, скоклько у тебя btc на каких адресах.
Ну скажем так я выяснил что там пахнет во всяком случае кучей адресов и множеством HD путей, так называемые пути дериваци.
Например если я введу свою мнемоническую фразу в кошелек Electrum, там например есть некое кол-во монет, но например если я куплю Trezor One и попробую воспользоватся этой же фразой там, я так понимаю там будет пусто.
Нет, не коснулась, так как я понимаю что это глупо, ведь возможных мнемонических фраз из 12 слов 340282366920938463463374607431768211455, а только в декабре 21го года кошельков с не нулевым балансом 40млн, то есть пустых адресов где-то 340282366920938463463374607431728211455, это как искать иголку в стоге сена.
i3a4em, если вычислить root key, на сколько я понимаю там пусто.

gnifajio

Gnifajio None @gnifajio Автор вопроса
Если что то знаешь, буду благодарен.
https://qna.habr.com/q/1130906

Noizefan

Короче похоже это коммерческая тайна, сам ничего не нашел.
Возможно пишут в бд индекс адреса и так и запоминают

Ответ написан более года назад
Комментировать
Нравится Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

python

  • Python
  • +1 ещё

Error Connecting: HTTPSConnectionPool(host=’url’, port=443) как решить?

  • 1 подписчик
  • 2 часа назад
  • 10 просмотров

Что это?

Cryptronics — это удобная и простая Python обёртка для криптовалютных API сервисов:

  • octopusapisoftware.com (usdt TRC20)
  • cryptocurrencyapi.net (btc, ltc, doge, dash, bch)
  • etherapi.net (eth)
  • bnbapi.net (bnb)

Как этим пользоваться?

Выше был приведен список сервисов, а так же список поддерживаемых ими монет. Вам необходимо зарегистрировать аккаунты в зависимости от необходимых вам монет и сгенерировать API ключи в личном кабинете каждого из сервисов.

Импорт и настройка

Для начала работы необходимо импортировать класс Crypto и инициализировать его, передав в качестве параметров Ваши ключи. Обратите внимание, что передавать все ключи не обязательно, можете указывать только для необходимых Вам сервисов.

create_wallet(token, tag)

В качестве параметров принимает:

  • *token — тикер токена, под который нужно создать кошелек (usdt, btc, etc. )
  • *tag — метка, идентификатор. Нужна для идентификации операции в апи сервисе

Ниже приведен пример создания кошелька для пользователя, где в качестве тэга используется строка с вставленным в неё ID пользователя

В response вернется словарь (dict) с адресом только что созданного кошелька и иной информацией в зависимости от задействованного API сервиса

send(token, to_address, amount, tag)

Токены будут отправлены с Вашего ОСНОВНОГО кошелька. Подробнее о принципах работы системы можете почитать в документации к octopusapisoftware или cryptocurrency В качестве параметров принимает:

  • *token — тикер токена, под который нужно создать кошелек (usdt, btc, etc. )
  • *to_address — адрес для отправки токенов (с основного кошелька)
  • *amount — Кол-во монет для отправки
  • tag — метка, идентификатор. Нужна для идентификации кошелька в апи сервисе
  • mix — Отправлять монеты через миксер (True/False)

Ниже приведен пример вывода средств пользователю вашей системы. В качестве аргументов передан токен usdt, адрес пользователя стандарта TRC20 , сумма и тэг

В response вернется словарь (dict) с ID вашей транзакции в блокчейн сети и иной информацией в зависимости от задействованного API сервиса.

generate_wallets(tokens, tag)

В качестве параметров принимает:

  • tokens — список (list) тикеров валют, для которых необходимо создать кошельки
  • tag — уникальный тэг, для отслеживания операции в API сервисе (желательно включать в него id пользователя внутри вашей системы)

Ниже приведен пример генерации кошельков по всем доступным API сервисам

Вернется список (list), в котором будут находится сгенерированные кошельки.

TODO:

  • Возможность сгенерировать кошельки по нескольким валютам, для которых указан токен
  • Возможность отправки монет с использованием крипто-миксера (через биржи)
  • Возможность получить баланс кошелька, указав токен или сервис
  • Добавить возможность отслеживать количество подтверждений транзакции в блокчейн сети
  • Возможность отслеживать ожидаемое пополнение фиксированной, заранее известной суммы

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *