Compressed address bitcoin что это

Какие форматы бывают у биткоин-адресов?

Что такое биткоин-адрес в формате legacy?

Legacy-адрес — это стандартный для сети биткоина адрес, предложенный Сатоши Накамото. Иначе это формат называют P2PKH (Pay To Public Key Hash), поскольку он требует от получателя подпись, вычисленную из приватного ключа, и публичный ключ. Скрипт транзакции выхода с помощью криптографических функций сверяет их с хешем публичного ключа — и в случае совпадения позволяет расходовать средства. Вероятность того, что система примет некорректно введенный адрес составляет 1 в 232 степени, то есть один случай из 4,29 млрд.Legacy-адрес можно узнать по префиксу 1 (и m или n в тестовой сети). К основным минусам такого адреса относятся чувствительность к регистру при вводе данных, более высокие комиссии за операции, низкая скорость двойного хеширования контрольной суммы, больший вес в QR-кодах и неудобство записи на мобильном устройстве или на бумаге.

Из каких частей состоит биткоин-адрес в формате legacy?

Legacy-адреса уникальны, обычно состоят из 26-35 символов и представляют собой 160-битные хэши открытого ключа ECDSA ключевой пары. С появлением SegWit-адресов их стали называть старыми, однако изначально они были достаточно эффективным средством представления locking scripts в более удобном для пользователей виде и уменьшения рисков отправки средств на некорректный адрес.Стандартный биткоин-адрес состоит из таких частей:

  • префикс;
  • сгенерированный в результате применения к приватному ключу алгоритмов SHA256 и RIPEMD публичный ключ;
  • контрольная сумма.

Почему в биткоин-адресах бывает разное количество знаков?

Как зашифрованы части legacy-адреса?

Все части биткоин-адреса в формате legacy зашифрованы с защитой от опечаток по системе кодирования Base58Check. В основе кода лежит латинский алфавит. Вы никогда не увидите в таком биткоин-адресе символы, которые легко спутать между собой (знаки плюс и минус, косая черта, ноль, прописные буквы “o” и “i”, строчная “L”). Согласно системе Base58Check в них применяются только следующие 58 символов:

Что такое биткоин-адрес в формате P2SH?

P2SH-адреса (Pay to script hash) появились в предложении по улучшению биткоина BIP-0016 в январе 2012 года благодаря главному научному сотруднику Bitcoin Foundation Гэвину Андресену. Они имеют ту же структуру, что и legacy-адреса, но начинаются с цифры 3.Такие адреса предполагают, что при переводе средств получатель должен иметь скрипт, подходящий к скрипту хеша. Эта особенность позволяет снижать комиссию за перевод биткоинов отправителем, перекладывать комиссионные затраты на получателя и создавать адреса с мультиподписью.

Технология P2SH может разрешить использование средств любым пользователем или, наоборот, запретить для всех. Важно помнить, что биткоин-адреса в формате P2SH поддерживают SegWit, но не являются его нативным решением. Не поддерживающие SegWit криптокошельки могут проводить SegWit-транзакции благодаря механизмам P2WPKH-в-P2SH и P2WSH-в-P2SH.

Что такое биткоин-адрес в формате SegWit?

  • легко читаемой человеком части,
  • разделителя (1),
  • данных и контрольной суммы.

Если при введении адреса было допущено до четырех ошибок, контрольная сумма, входящая в Bech32-адрес, не сойдется. Благодаря примененному в решении коду Боуза-Чоудхури -Хоквингема (БЧХ-коду) ошибки будут автоматически исправлены.
При записи Bech32-адрес применяются следующие 32 символа:

Какие плюсы и минусы использования Bech32-адресов?

C новыми адресами QR-коды стали меньше, а защита от ошибки выше. Кроме того, использование биткоин-адресов в формате Bech32 на сегодня для пользователей более выгодно, ведь комиссия за отправку средств с них ниже, а скорость обработки выше. Главный минус Bech32-адресов — их поддерживают не все криптокошельки и сервисы.Среди первых поддержку таких адресов добавили аппаратные криптокошельки Ledger Nano S, TREZOR и Digital Bitbox, десктоп-криптокошельки Electrum и Armory, мобильные криптокошельки Edge, GreenAddress (для iOS- и Android-устройств), а также Samourai Wallet, Wasabi Wallet, GreenBits и Electrum (для Android-устройств).

Можно ли переводить биткоины с legacy-адреса на SegWit-адрес?

Активация SegWit в сети биткоина была софтфорком — это значит, что новая и предыдущая версии сохранили совместимость. То есть вы можете без проблем переводить средства с legacy-адреса на SegWit-адреса. На уровне блокчейна проблем с разницей в форматах адресов не существует.На практике сложности возникают, если пользователь хочет перевести средства со своего legacy-адреса, например, созданного на криптобирже, на bc1-адрес, а торговая площадка технически еще не внедрила поддержку нового формата адресов. В таком случае стоит использовать пусть и менее эффективный, чем bc1-, но все же более продвинутый, чем legacy- P2SH-адрес.

В обратном направлении, с bc1-адреса на legacy-адрес, средства должны поступить без проблем.

Какие обозреватели блоков отслеживают bc1-адреса?

Источник

Почему Bitcoin поддерживает сжатые и несжатые ключи /адреса?

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

Итак, вот что я сделал: я использовал dumpprivkey для адреса (183Tw2TqXKkbk5ZeocTYwmxg8x46ADXb6c) в клиенте .7.2 и получил L5DTi7rgqsPg7Vq1vTU2dP2HWMEsNM5w5JCqEDXXXXXXXXXXXX. Когда я вставлял это в файл описания кошелька bitaddress.org , он возвратил несколько вещей. Во-первых, он показал другой адрес (1FKswUuFsjWKyr4ZPSe3vEpp1iCXXChBZm), но он также показал адрес выше и сказал, что это сжатая версия. Я отправил, как 0.0001, на каждый из двух адресов, и мой клиент сатоши показывает транзакцию, полученную с 183 (сжатого) адреса.

Может ли кто-нибудь объяснить на практике, какая разница и почему они оба существуют в Биткойне? Любая помощь приветствуется.

3 ответа

Причина, по которой они существуют, состоит в том, что Сатоши не знал о сжатых открытых ключах, и только недавно было обнаружено, что их можно будет использовать без проблем совместимости (поддержка существует только с версии 0.6 ссылочного клиента) .

Преимущество ясно: их открытые ключи меньше, что приводит к меньшим транзакциям в сети, сохраняя размер цепочки блоков для всех.

Обновление: внутри SegWit тратится только сжатые ключи.

«Тем не менее, не должен ли клиент post-0.6.0 распознавать как отправку на сжатый адрес, так и отправку на несжатый адрес, потому что у него есть закрытый ключ, достаточный для проведения?» Quizzical Nov 27 ’13 at 2:16 «

У вас есть закрытый ключ? Большой! Откройте bitaddress.org (офлайн) и перейдите на вкладку сведений о бумажнике, затем введите закрытый ключ. Вы найдете сжатые и несжатые адреса в правой и левой частях соответственно. Прокрутите вниз, вы увидите сжатые и несжатые личные ключи. Да! Частные ключи, если они обозначены в контрольном формате базы 58, имеют разные значения в сжатой и несжатой форме. Это было сделано для того, чтобы клиенты не путались относительно того, какой адрес для сопоставления (сжатый или несжатый).

Дело в том, что формат WIF для каждого шестнадцатеричного закрытого ключа отличается в сжатой и несжатой форме. Надеюсь, что этот ответ поможет.

Читайте также:  1 определить коэффициент дисконтирования по инвестициям

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

Это связано с тем, что открытый ключ:

Пока несжатая версия этого открытого ключа:

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

Источник

Виды биткоин адресов

Биткоин – это универсальная криптовалютная платежная система, имеющая массу преимуществ, которые ставят ее на несколько ступеней выше традиционных финансовых, банковских и платежных инструментов, будь-то Visa, Mastercard, PayPal и т.д.

Использование биткоина имеет множество позитивных моментов, среди которых:

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

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

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

Что такое биткоин-адрес?

Биткоин адрес – это уникальный публичный идентификатор, использующийся для обозначения пункта назначения отправляющихся через блокчейн монет BTC. Фактически это адрес получателя биткоинов, подобный номеру банковского счета.

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

Форматы биткоин адресов

Существуют следующие форматы биткоин адресов:

  1. Pay-to-Pub key Hash (P2PKH) – начинаются на 1, например, 14eQD1QQb8QFVG8YFwGz7skyzsvBLWLwJS (адрес биржи Kraken). Это первоначальные (Legacy) адреса биткоина, защищенные одним ключом ECDSA;
  2. Pay to Scrypt Hash (P2SH) – более защищенные адреса, начинающиеся на цифру 3, например, 3M6UcBNGZAW1HRjiFDMRcY5aXFrQ4F9E1y (Binance). Они защищены 3 ключами ECDSA;
  3. Bech32 — segwit- адреса, использующиемся с 2017 года согласно апгрейду сети биткоина по BIP 0173, начинаются на bc1, например, bc1qgdjqv0av3q56jvd82tkdjpy7gdp9ut8tlqmgrpmv24sq90ecnvqqjwvw97 (адрес биржи Bitfinex). Эти адреса имеют самую лучшую защищенность, но могут иметь проблемы несовместимости с очень старыми wallets (в новых кошельках этих проблем нет). Обработка segwit-транзакций в сети более быстрая, а также требует меньшей комиссии.

Некоторые альткоины, например, BitcoinCash (BCH) используют аналогичные форматы адресов.

Кроме того, существуют биткоин-адреса, начинающиеся на 2, но они используются только в тестовой сети.

Каждый биткоин адрес уникален и составляется из 58 цифробуквенных символов (стандарт base58check):

  • разных регистров у старых адресов формата P2PKH и P2SH;
  • в любом регистре у bech32-адресов (их символы можно записывать как угодно).

Обычно биткоин-адреса имеют длину в 26-35 символов и начинаются на цифру 3 или 1. Для того, чтобы избежать путаницы в биткоин адресах не используют буквы O и I верхнего регистра (заглавные), букву l в нижнем регистре (маленькая L) и не применяют число 0.

В стандартном биткоин-адресе есть три части:

  • префикс;
  • публичный ключ, сгенерированный из приватного ключа с использованием алгоритмов RIPEMD и SHA256;
  • контрольная сумма.

Длина биткоин адреса в пределах 26-35 символов меняется из-за того, что при обработке приватного ключа могут образовываться начинающиеся на ноль числа. Их длина сокращается из-за того, что нули при записи отбрасываются.

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

Существуют адреса, на которых отправка средств требует применения нескольких приватных ключей – это так называемые Multi-signature addresses. Использование таких адресов позволяет обезопасить управление средствами, которыми владеют несколько лиц. Так как это более новый тип адресов, они не могут начинаться на единицу.

Как создать биткоин адрес?

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

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

Существуют кошельки для настольных компьютеров (например, Electrum), мобильных устройств (например, Jaxx и Coinomi), а также web-кошельки (например, Blockchain.info).

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

Как обеспечить безопасность биткоин адреса?

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

Опасность таится не только в хакерах, но и в недобросовестных владельцах бирж, например, Poloniex.

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

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

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

Источник

Blockchain на Go. Часть 5: Адреса

Вступление

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

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

Биткоин-адрес

Вот пример Bitcoin-адреса: 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa. Это самый первый Bitcoin-адрес, который якобы принадлежит Сатоши Накамото. Bitcoin-адреса находятся в открытом доступе. Если вы захотите отправить кому-то монеты, вам нужно знать адрес получателя. Но адреса (несмотря на уникальность) не являются идентификатором вас, как владельца «кошелька». Фактически, такие адреса являются открытым ключом. В Bitcoin ваша личность — это пара (или пары) закрытых и открытых ключей, хранящихся на вашем компьютере (или в каком-либо другом месте, к которому у вас есть доступ). Для создания таких ключей используются криптографические алгоритмы, которые гарантируют, что никто другой не сможет получить доступ к вашим монетам без физического доступа к вашим ключам. Давайте рассмотрим, что же это за алгоритмы.

Читайте также:  Самые популярные криптовалюты для майнинга 2021

Криптосистема с открытым ключом

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

По сути, Bitcoin-кошелек — это всего лишь пара таких ключей. Когда вы устанавливаете приложение кошелька или используете Bitcoin клиент для создания нового адреса, для вас генерируется пара ключей. Тот, кто контролирует закрытый ключ, контролирует все монеты, которые были на него отправлены.

Закрытые и открытые ключи — это просто случайные последовательности байтов, поэтому они не могут быть напечатаны на экране и прочитаны человеком. Вот почему Bitcoin использует алгоритм для преобразования открытых ключей в удобочитаемую строку.

Если вы когда-нибудь использовали Bitcoin кошелек в виде приложения, вероятно, для вас была создана мнемоническая фраза. Такие фразы используются вместо закрытых ключей и могут быть использованы для их генерации. Этот механизм реализован в BIP-039.

Итак, теперь мы знаем, что идентифицирует пользователей в Bitcoin. Но как Bitcoin проверяет владельца выхода транзакции (и монеты, которые там хранятся)?

Электронная цифровая подпись

В математике и криптографии существует концепция электронной цифровой подписи — алгоритмы, которые гарантируют:

  1. что данные не были изменены при передаче от отправителя к получателю;
  2. что данные были созданы определенным отправителем;
  3. что отправитель не может отрицать то, что именно он отправил эти данные.

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

Чтобы подписать данные, нам понадобится следующее:

  1. данные для подписи;
  2. закрытый ключ.

Алгоритм создает подпись, которая хранится во входах транзакции. Чтобы проверить подпись, необходимо следующее:

  1. данные, которые были подписаны;
  2. подпись;
  3. открытый ключ.

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

Цифровые подписи не шифруются, а данные получить из нее невозможно. Это похоже на хеширование: вы преобразуете данные при помощи алгоритма и получаете их уникальное представление. Разница между хешем и подписью — это пары ключей, которые позволяют произвести проверку последней.
Но такие пары ключей также можно использовать и для шифрования данных: для шифрования используется закрытый ключ, а для расшифровки — открытый. Однако же Bitcoin не использует алгоритмы шифрования.

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

  1. Проверку того, что входы имеют достаточные права на использование выходов из предыдущих транзакций.
  2. Проверку правильности подписи транзакции.

Схематически, процесс подписи и проверки данных выглядит так:

Давайте рассмотрим полный жизненный цикл транзакции:

  1. В самом начале содержится блок генезиса с coinbase транзакцией. В транзакциях coinbase нет реальных входов, поэтому подпись не требуется. Вывод транзакции содержит хешированный открытый ключ (используются алгоритмы RIPEMD16(SHA256(PubKey)) ).
  2. Когда кто-то отправляет монеты, создается транзакция. Входы транзакции будут ссылаться на выходы из предыдущих транзакций. Каждый вход будет хранить открытый ключ (не хешированный) и подпись всей транзакции.
  3. Другие узлы в сети Bitcoin, которые получат транзакцию, тоже проверят ее. Помимо прочего, здесь происходит сопоставление хеша открытого ключа на входе транзакции с хешом соответствующего выхода, (это гарантирует, что отправитель тратит только принадлежащие ему монеты); подпись правильная (это гарантирует, что транзакция создана реальным владельцем монет).
  4. Когда узел готов к майнингу нового блока, он поместит транзакцию в блок и начнет добывать ее.
  5. Когда блок добыт, каждый другой узел в сети получает сообщение о том, что блок добыли и добавляет его в цепь.
  6. После того, как блок добавлен в цепь, транзакция завершена, теперь на ее выходы можно ссылаться в новых транзакциях.

Эллиптическая криптография

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

Bitcoin использует эллиптические кривые для генерации секретных ключей. Эллиптические кривые — это сложная математическая концепция, которую мы не будем здесь подробно объяснять (если интересно, можете почитать об этом здесь ПРЕДУПРЕЖДЕНИЕ: очень много математики!). Кривая, используемая Bitcoin, может случайным образом выбирать число между 0 и 2²⁵⁶ (что составляет приблизительно 10⁷⁷, на заметку, атомов в видимой вселенной где-то между 10⁷⁸ и 10⁸²). Такой предел означает, что почти невозможно сгенерировать один и тот же закрытый ключ дважды.

Кроме того, Bitcoin использует (и мы будем) алгоритм ECDSA для подписи транзакций.

Base58

Теперь давайте вернемся к вышеупомянутому адресу 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa. Теперь мы знаем, что это общепринятое для человека представление открытого ключа. И если мы его декодируем, он будет выглядеть примерно так (как последовательность байтов, записанных в шестнадцатеричной системе):

Bitcoin использует алгоритм Base58 для преобразования открытых ключей в читаемый человеком формат. Алгоритм очень похож на известный Base64, но он использует более короткий алфавит: некоторые буквы были удалены из алфавита, чтобы избежать гомографические атаки. В связи с этим, в этом алфавите отсутствуют следующие символы: 0 (ноль), О (заглавная буква «о»), I (заглавная «i»), l (строчная «L») а также знаки «+» и «/».

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

Следуя этой схеме, ключ, который мы привели выше, разделен на три части:

Хорошо, теперь, когда мы собрали все воедино, пришло время писать код! Я надеюсь, что сейчас все, что было непонятным прояснится.

Реализация адресов

Начнем со структуры кошелька Wallet

Кошелек — не что иное, как пара ключей. Нам также понадобится тип Wallets , чтобы хранить коллекцию кошельков, сохранять их в файл и выгружать их из него. В конструкторе Wallet создается новая пара ключей. Функция newKeyPair проста, здесь мы используем ECDSA. Затем создается закрытый ключ с использованием кривой, и открытый ключ генерируется при помощи закрытого ключа. Одно замечание: в алгоритмах на основе эллиптической кривой открытые ключи являются точками на кривой. Таким образом, открытый ключ представляет собой комбинацию координат X, Y. В Bitcoin эти координаты объединяются и образуют открытый ключ.

Читайте также:  Nvidia выпустит карты для майнинга

Теперь, создадим функцию генерации адреса:

Разберем по шагам преобразование открытого ключа в адрес Base58:

  1. Возьмем открытый ключ и запишем его дважды с помощью алгоритмов хеширования RIPEMD160 (SHA256 (PubKey)) .
  2. Подготовим версию.
  3. Вычислим контрольную сумму путем хеширования результата из шага 2 и SHA256 (SHA256 (payload)) . Контрольная сумма — это первые четыре байта полученного хеша.
  4. Добавим контрольную сумму в комбинацию version+PubKeyHash .
  5. Зашифруем комбинацию version+PubKeyHash+checksum при помощи Base58.

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

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

Теперь нам нужно изменить входы и выходы для использования адресов:

Обратите внимание, что мы больше не используем поля ScriptPubKey и ScriptSig , вместо этого ScriptSig разделяется на поля Signature и PubKey , а ScriptPubKey переименован в PubKeyHash . Мы будем реализовывать те же функции блокировки/разблокировки выходов и логику подписей входов, как в Bitcoin, но реализуем мы это при помощи методов.

Метод UsesKey проверяет, что вход использует определенный ключ для разблокировки выхода. Обратите внимание, что входы хранят нехешированные открытые ключи, а функция принимает хешированный. IsLockedWithKey проверяет, был ли использован хеш-ключ открытого ключа для блокировки выхода. Это дополнительная функция для UsesKey , и они обе используются в FindUnspentTransactions для построения соединений между транзакциями.

Lock просто блокирует выход. Когда мы отправляем монеты кому-то, нам известен только адрес, поэтому функция принимает адрес как единственный аргумент. Затем адрес декодируется, а хеш-ключ открытого ключа извлекается из него и сохраняется в поле PubKeyHash .

Теперь давайте проверим, что все работает правильно:

Отлично! Пришла пора реализовать подписи транзакций.

Реализация подписей

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

У нас есть все для реализации подписей к транзакциям, кроме одного: данных для подписи. Какую часть транзакции мы должны подписывать? Или же необходимо подписывать сделку в целом? Выбор данных для подписи очень важен. Дело в том, что данные, которые должны быть подписаны, должны содержать информацию, которая идентифицирует данные уникальным образом. Например, нет смысла подписывать только выходные значения, потому что такая подпись не будет учитывать отправителя и получателя.

Учитывая, что транзакции разблокируют предыдущие выходы, перераспределяют их значения и блокируют новые выходы, должны быть подписаны следующие данные:

  1. Хеши открытых ключей хранящиеся в разблокированных выходах. Это идентифицирует «отправителя» транзакции.
  2. Хеши открытых ключей хранящиеся в новых, заблокированных, выходах. Это идентифицирует «получателя» транзакции.
  3. Значения новых выходов.

В Bitcoin логика блокировки/разблокировки хранится в скриптах, которые хранятся в ScriptSig и ScriptPubKey полей входов и выходов соответственно. Поскольку Bitcoin допускает разные типы таких скриптов, он подписывает все содержимое ScriptPubKey .

В связи с этим в Bitcoin происходит подпись не транзакции, а ее обработанной копии со входами, содержащими ScriptPubKey указанного выхода

Здесь описан подробный процесс обработки копии транзакции. Скорее всего, он устарел, но мне не удалось найти более надежный источник информации.

Все это выглядит достаточно сложным, давайте начнем писать код. А начнем мы с метода Sign :

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

Давайте внимательнее рассмотрим этот метод:

Coinbase транзакции не подписаны, так как в них нет реальных выходов

Мы подписываем обработанную копию, а не всю транзакцию:

Копия будет включать все входы и выходы, а TXInput.Signature и TXInput.PubKey будут равны nil.

Затем пройдемся по каждому входу в копии:

На каждом входе Signature устанавливается на nil (просто двойная проверка), а PubKey присваиваем ссылку на выход в PubKeyHash . В настоящий момент все транзакции, кроме текущей, являются «пустыми», то есть поля подписи и PubKey равны нулю. Таким образом, входы подписываются отдельно, хотя это необязательно для нашего приложения, но Bitcoin позволяет транзакциям содержать входы, ссылающиеся на различные адреса.

Метод Hash сериализует транзакцию и хеширует ее с помощью алгоритма SHA-256. Результатом являются данные готовые для подписи. После получения хеша мы должны сбросить поле PubKey , чтобы не было влияния на наши дальнейшие итерации.

Мы подписываем txCopy.ID при помощи privKey . Подпись ECDSA представляет собой пару чисел, которые мы объединяем и сохраняем в поле входа Signature .

Рассмотрим функцию верификации:

Метод довольно простой. Для начала получим копию транзакции, как в прошлом методе:

Затем нам понадобится кривая, которая используется для генерации пар ключей:

Затем пройдемся по всем входам и проверим, что они подписаны:

Эта часть идентична той, что используется в методе Sign, так как во время проверки нам нужны те же самые данные, что мы и подписывали

Здесь мы распаковываем значения, хранящиеся в TXInput.Signature и TXInput.PubKey , так как сигнатура представляет собой пару чисел, а открытый ключ — это пара координат. Мы конкатенировали их раньше для хранения, и теперь нам нужно их распаковать для использования в функциях crypto/ecdsa .

Теперь мы создаем ecdsa.PublicKey , используя открытый ключ, который мы берем из входа, и выполняем ecdsa.Verify , передавая подпись, из входа. Если все входы проверены, мы возвращаем true; если хотя бы один вход не прошел проверку, возвращаем false.

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

FindTransaction находит транзакцию по идентификатору (для этого требуется итерация по всем блокам в цепи); SignTransaction берет одну транзакцию, находит транзакции, на которые она ссылается, и подписывает ее; VerifyTransaction просто проверяет транзакцию.

Теперь нам нужно подписать и проверить транзакции. Подписывать мы будем в методе NewUTXOTransaction :

Проверка транзакции происходит до того, как она будет добавлена в блок:

Вот и все! Давайте проверим все еще раз:

У нас даже ничего не сломалось, удивительно!

Давайте закомментируем вызов bc.SignTransaction (& tx, wallet.PrivateKey) в NewUTXOTransaction , для гарантии того, что неподписанные транзакции нельзя будет майнить:

Заключение

Мы реализовали почти все ключевые особенности Bitcoin и это потрясающе. А в следующей части мы наконец-таки завершим реализацию транзакций.

Источник

Оцените статью