Чт. Фев 22nd, 2024

В наше время создание биткоин-транзакции стало гораздо проще. Существуют специальные доверенные онлайн-сервисы, которые позволяют отправить вашу транзакцию в сеть бесплатно (без учета комиссии сети) и безопасно, без необходимости устанавливать локальную ноду биткоина и скачивать весь блокчейн. К тому же, для работы с этими сервисами есть удобные библиотеки для Python.

Давайте установим библиотеку «bit»:

pip install bit

Ключи

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

Существует две сети в мире Биткоина — главная и тестовая, каждая со своими ключами и видами адресов. Для главной сети, где адреса обычно начинаются с цифры, можно генерировать новые ключи с помощью класса Key:

from bit import Key
key = Key()
print(key.address)  # 1C8REeQUnXE3HtLCYXVG21AryDxRXnnyar

Класс Key является псевдонимом для PrivateKey:

from bit import Key, PrivateKey
print(PrivateKey is Key)  # true

Для демонстрационных целей, вы можете использовать тестовую сеть, где монеты не имеют стоимости и легко доступны. Адреса в тестовой сети обычно начинаются с буквы «m» или «n». Создание нового ключа для тестовой сети можно сделать с помощью класса PrivateKeyTestnet:

from bit import PrivateKeyTestnet
k = PrivateKeyTestnet()
print(k.address)  # mrzdZkt4GfGMBDpZnyaX3yXqG2UePQJxpM

Если при создании экземпляра класса ключа не указать параметры, то каждый раз будет создаваться новый адрес (вероятно, с нулевым балансом). Этот процесс происходит локально, без обращения к онлайн-сервисам, и очень быстро. Однако, следует помнить, что если приватный ключ не сохранен, то после завершения программы доступ к адресу будет утрачен. Поэтому для сохранения приватного ключа его стоит сгенерировать и записать в безопасном месте, например, в блокноте.

Для получения адреса используется свойство k.address, а для получения приватного ключа в удобном формате, чаще всего используется WIF (Wallet Export Format), который можно получить с помощью метода k.to_wif():

from bit import PrivateKeyTestnet as Key
k = Key()
print('Private key:', k.to_wif())
print('Public address:', k.address)
# Private key: cQqh9xFys2KJyWhHMaBwG2kFLCNBCmTgxVqnPTXK6Vng4vU6igoV
# Public address: mhnmzFN5gr6gvmEr1t8UcRh6rdTh6JxuDe

Также по приватному ключу можно получить SegWit адрес, который обычно работает быстрее, чем традиционные адреса:

print(k.segwit_address)  # 2MsWNuzx8EfgEeGLesLmkMM6q3kajEjVnVh

Пока идет транзакция, мы можем воспользоваться биткоин-краном, чтобы получить немного тестовых монет бесплатно. Важно помнить, что транзакция может занять некоторое время, около 10-20 минут, поэтому требуется немного терпения.

Также, если у нас уже есть сохраненная секретная строка приватного ключа, мы можем создать экземпляр класса ключа с помощью этой строки:

from bit import PrivateKeyTestnet as Key
k = Key('cQqh9xFys2KJyWhHMaBwG2kFLCNBCmTgxVqnPTXK6Vng4vU6igoV')
print(k.address)  # mhnmzFN5gr6gvmEr1t8UcRh6rdTh6JxuDe

В результате получаем тот же адрес, что и ранее.

Приватный ключ может быть представлен в различных форматах, таких как число, байты, HEX-строка, WIF, DER и PEM. Для демонстрации этого, используется класс PrivateKeyTestnet из библиотеки «bit», в котором создается экземпляр ключа с помощью секретной строки «cQqh9xFys2KJyWhHMaBwG2kFLCNBCmTgxVqnPTXK6Vng4vU6igoV».

Далее, происходит вывод значений приватного ключа в различных форматах:

from bit import PrivateKeyTestnet as Key
k = Key('cQqh9xFys2KJyWhHMaBwG2kFLCNBCmTgxVqnPTXK6Vng4vU6igoV')
print('Int:', k.to_int(), end='\n\n')
print('Hex:', k.to_hex(), end='\n\n')
print('Bytes:', k.to_bytes(), end='\n\n')
print('WIF:', k.to_wif(), end='\n\n')
print('DER:', k.to_der(), end='\n\n')
print('PEM:', k.to_pem(), end='\n\n')

Результаты вывода:

Int: 4397583691621789343100573085...453641742227689755261559235
Hex: 6139710fb66e82b7384b868bda1ce59a0bd216e89b8808ae503c5767e4d461c3
Bytes: b'a9q\x0f\xb6n\x82\xb78K\x86\x8b\xd...d4a\xc3'
WIF: cQqh9xFys2KJyWhHMaBwG2kFLCNBCmTgxVqnPTXK6Vng4vU6igoV
DER: b'0\x81\x84\x02\...xb3b\x8e\x1ar\xc6'
PEM: b'-----BEGIN PRIVATE KEY-----\nMIGEA.....O\nrRnD/Ls2KOGnLG\n-----END PRIVATE KEY-----\n'

Также существует удобная функция wif_to_key из библиотеки «bit», которая позволяет создавать класс ключа из WIF формата. Эта функция сама определит тип сети и создаст нужный класс. Пример использования:

from bit import wif_to_key
k = wif_to_key('cQqh9xFys2KJyWhHMaBwG2kFLCNBCmTgxVqnPTXK6Vng4vU6igoV')
print(k)  # <PrivateKeyTestnet: mhnmzFN5gr6gvmEr1t8UcRh6rdTh6JxuDe>

Предполагаю, что монеты уже успешно получены с биткоин-крана, и мы можем продолжить работу с кодом.

Баланс

Для того чтобы узнать баланс нашего кошелька, мы используем библиотеку «bit», которая обращается к онлайн-сервисам (https://insight.bitpay.com, https://blockchain.info, https://smartbit.com.au) для этой операции. Однако, следует учитывать, что эта операция не моментальная и может занять некоторое время.

Пример кода для получения баланса:

from bit import PrivateKeyTestnet as Key
k = Key('cQqh9xFys2KJyWhHMaBwG2kFLCNBCmTgxVqnPTXK6Vng4vU6igoV')
print(k.get_balance())  # 1391025

В данном примере, на момент выполнения операции, на адресе нашего кошелька лежало 1391025 сатоши. Один сатоши равен одной стомиллионной части целого биткоина (10^(-8)), что является самой маленькой неделимой частичкой.

Библиотека «bit» также предоставляет удобный встроенный конвертер валют, что позволяет получить баланс в любой поддерживаемой валюте. Например:

print(k.get_balance('mbtc'), 'MBTC')  # 13.91025 MBTC
print(k.get_balance('usd'), 'USD')  # 129.84 USD
print(k.get_balance('rub'), 'RUB')  # 8087.35 RUB

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

Как послать монеты?

Очень просто отправить биткоины с помощью метода send. Давайте создадим еще один ключ (dest_k) и отправим ему часть биткоинов от ключа source_k.

from bit import PrivateKeyTestnet as Key

# Создаем ключи
source_k = Key('cQqh9xFys2KJyWhHMaBwG2kFLCNBCmTgxVqnPTXK6Vng4vU6igoV')
dest_k = Key('cP2Z27v1ZaBz3VQRRSTQRhgYt2x8BtcmAL9zi2JsKaDBHobxj5rx')

# Выводим информацию об отправке
print(f'Send from {source_k.address} to {dest_k.address}')

# Отправляем биткоины
r = source_k.send([
    (dest_k.address, 0.0042, 'btc')
])

print(r)  # ID транзакции

В данном примере мы создали ключи source_k и dest_k. Затем, используя метод send, отправляем 0.0042 биткоина с адреса source_k на адрес dest_k. Обратите внимание, что у транзакции может быть много выходов, и первый аргумент функции send представляет список, в котором указывается кому и сколько мы отправляем (кортеж: адрес, количество, валюта). Здесь мы имеем одного адресата dest_k и второй неявный выход – обратно наш же адрес (source_k), чтобы получить сдачу.

После отправки транзакции, мы можем проверить список транзакций и непотраченные входы у ключа source_k:

# Проверим список транзакций
transactions = source_k.get_transactions()
print(transactions)
# ['a101ad526e9fb131b90aac220b8b6e8bf11b9b9848ab8ea6d4384dc5b4ccece0', '0770f10a7b130852e38d9af44e050c9188664c12f2d31a56a62d6648a73e1264']

# Проверим непотраченные входы (неизрасходованные выходы)
unspents = source_k.get_unspents()
print(unspents)
# [Unspent(amount=967861, confirmations=4, script='76a91418ee4d98c345db083114990baa17d02e988cfedb88ac', txid='a101ad526e9fb131b90aac220b8b6e8bf11b9b9848ab8ea6d4384dc5b4ccece0', txindex=1, segwit=False)]

Таким образом, после выполнения операции мы можем получить ID транзакции и проверить список транзакций и непотраченные входы у ключа source_k. Это позволяет отслеживать и контролировать состояние кошелька после совершения транзакции.

Давайте рассмотрим пример использования функции send для отправки биткоинов нескольким адресатам:

my_key.send([
    ('1HB5XMLmzFVj8ALj6mfBsbifRoD4miY36v', 0.0035, 'btc'),
    ('1Archive1n2C579dMsAu3iC6tWzuQJz8dN', 190, 'jpy'),
    ('129TQVAroeehD9fZpzK51NdZGQT4TqifbG', 3, 'eur'),
    ('14Tr4HaKkKuC1Lmpr2YMAuYVZRWqAdRTcr', 2.5, 'cad')
])

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

Также, если мы хотим вернуть сдачу не себе, а на другой адрес, мы можем использовать аргумент «leftover»:

key.send(..., leftover='адрес_для_сдачи')

Если нам нужно прикрепить к транзакции сообщение (до 40 байт в кодировке UTF-8), мы можем использовать аргумент «message»:

key.send(..., message='За кофе и пончик')

Строка create_transaction, с другой стороны, создает транзакцию и подписывает ее ключом, но не отправляет ее в сеть. Все аргументы для create_transaction те же, что и для send.

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

Комиссии

Если комиссия не указана явно при создании транзакции, то она будет автоматически рассчитана по средним значениям, учитывая длину транзакции. Средняя комиссия берется из онлайн-сервиса, который предоставляет эту информацию. Однако, есть возможность указать комиссию вручную, если это необходимо.

Примеры использования комиссии:

  1. Комиссия за байт: в данном случае, указанное значение будет умножено на количество байт в транзакции.
source_k.create_transaction(..., fee=72)
  1. Комиссия за всю транзакцию: если нужно указать комиссию за всю транзакцию целиком, а не за каждый байт отдельно, можно использовать аргумент «absolute_fee=True».
source_k.create_transaction(..., fee=200, absolute_fee=True)

Кроме того, есть полезные константы комиссий, которые могут быть использованы:

from bit.network import fees

fees.DEFAULT_FEE_FAST   # Комиссия, чтобы транзакция подтвердилась в течение 10 минут.
fees.DEFAULT_FEE_HOUR   # Комиссия, чтобы транзакция подтвердилась в течение 1 часа.

Таким образом, пользователь может выбрать способ задания комиссии, в зависимости от своих предпочтений и требуемой скорости подтверждения транзакции.

Советы

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

Однако, работа с внешними онлайн-сервисами может замедлять процесс. Если у вас есть доступ к своей собственной ноде биткоина, это может быть очень удобным решением, позволяющим выполнять все операции без задержек и ограничений. В таком случае, вы можете подключиться к вашей собственной ноде следующим образом:

from bit.network import NetworkAPI
# Подключение к тестовой ноде
NetworkAPI.connect_to_node(user='user', password='password', host='localhost', port='18443', use_https=False, testnet=True)
# Подключение к ноде главной сети
NetworkAPI.connect_to_node(user='user', password='password', host='domain', port='8332', use_https=True, testnet=False)
# Выберите нужное подключение или используйте оба

Не забывайте хранить свои приватные ключи в надежном месте!

Если вы использовали тестовые монеты с крана, пожалуйста, верните их обратно на адрес, который вам предложат. Они могут быть полезны другим разработчикам!

Библиотека bit также поддерживает работу с мульти-адресами, которые требуют 2 и более подписей для выполнения транзакции. Это предоставляет дополнительные возможности для безопасности и контроля над вашими средствами.

От admin

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

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

PHP Code Snippets Powered By : XYZScripts.com