Как получить публичные и частные дочерние ключи в биткойн-кошельке?

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



Как вы уже знаете, иерархические детерминированные кошельки (или HD-кошельки), которые мы собираемся использовать для этой цели, были впервые представлены в BIP 32 и улучшены БИП 44 позже.

HD кошелек - это древовидная структура открытый / закрытый ключ с общим родительским (корневым) узлом, обычно называемым главным узлом .

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

Расширенный ключ

Расширенные ключи - это Base58 закодированная версия сериализованных данных, которые объединяются в определенном порядке:

[version][depth][fingerprint][index][chain_code][serial]

Версия

4 байта, указывающие:

  • сеть, к которой принадлежит ключ: test (t) или main (x),
  • и тип ключа: public (pub) или private (prv).

Итак, в Биткойне эти байты версии являются tprv / xprv для закрытых ключей и
tpub / xpub для открытых ключей для тестовой и основной сети соответственно.

Глубина

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

Родительский отпечаток

Первые 4 байтов из hash160 сжатого родительского открытого ключа. У каждого xprv и xpub ключа по одному и тому же пути один и тот же отпечаток, поскольку у них обоих одинаковый родительский открытый ключ.

Реализация выглядит следующим образом:

И, как вы помните, хеширование происходит так:

Показатель

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

Диапазон индекса может быть от 0 до 4294967295 (или 2³²-1), где что-либо в 0..2147483647 следует за незакрепленным производным, а индексы в 2147483648..4294967295 следуют за усиленным производным. Мы можем определить охранников так:

Цепной код

Код, сгенерированный в предыдущей статье как часть расширенного ключа.

Последовательный

Либо открытый, либо закрытый 65 ключ длиной 24 байта с префиксом версии, 32 байтов взяты изx координаты графика эллиптической кривой, а следующие 32 байтов взяты из координаты y там .

Чтобы сериализовать открытый ключ, вам необходимо изменить его префикс с 0x04 на 0x02 или 0x03 в зависимости от того, является ли точка y открытого ключа (на графике эллиптической кривой) четным или нечетным числом. Реализация довольно проста:

С другой стороны, закрытый ключ немного отличается. Поскольку размер закрытого ключа составляет 32 байта, он должен быть объединен с префиксом 0x00 байта. Это сделано для того, чтобы размер закрытого ключа был ровно 33 байтов, как и размер сжатого открытого ключа.

Каждый биткойн закрытый ключ - это просто целое число от 1 до 115792089237316195423570985008687907852837564279074904382605163141518161494337 или HEX: от 1 до 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141. Целочисленный диапазон допустимых закрытых ключей регулируется secp256k1 ECDSA стандартом, используемым Биткойном.

Список путей

Иерархия HD-кошелька представлена ​​производным путем к первому адресу. Путь - это пара элементов, разделенных косой чертой /.

derivation_type / purpose' / coin_type' / account' / chain / index

В качестве примера, путь может выглядеть так: m/0/13'/3, где
' указывает, что BIP32 используется усиленная деривация.

Преобразовать такой путь в список целых чисел очень просто:

Каждый уровень на этом пути имеет собственное значение:

  • Тип деривации сообщает, какой тип ключа мы получаем: m для xprv и M для xpub.
  • Цель - это константа, равная 44' (или 0x8000002C) в соответствии с рекомендацией BIP43. Это указывает на то, что поддерево этого узла используется в соответствии с этой спецификацией.
  • Тип монеты - это постоянный набор для каждой криптовалюты. Разработчики криптовалюты могут зарегистрировать неиспользуемый номер для своего проекта. Список уже выделенных типов монет можно найти в разделе Зарегистрированные типы монет.
  • Учетные записи нумеруются, начиная с индекса 0, в порядке возрастания. Пользователи могут использовать эти счета для организации средств так же, как банковские счета: для пожертвований, для сбережений, для общих расходов и т. Д.
  • Константа 0 используется для внешней цепочки, а константа 1 - для внутренней цепочки. Внешняя цепочка используется для адресов, которые должны быть видны за пределами кошелька (например, для приема платежей). Внутренняя цепочка используется для адресов, которые не должны быть видны за пределами кошелька, и используется для изменения транзакции возврата.
  • Адреса нумеруются, начиная с индекса 0, в порядке возрастания.

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

                           /-- 0
                          /--- 1
root -- 44 -- 0 -- 0 -- 0 ---- 2   
                          \--- 3
                           \-- 4
  • частное производное
  • BIP44 соответствует требованиям
  • Биткойн криптовалюта
  • счет 0
  • цепь 0
  • индексы 0, 1, 2, 3, 4

Подпишитесь, чтобы сразу получать самые свежие материалы
https://tinyletter.com/KamilLelonek

Правила вывода

Стоит упомянуть несколько практических правил:

  • При изменении номера индекса создается другой несвязанный дочерний ключ от того же родителя.
  • Использование той же процедуры для дочерних ключей с дочерним цепным кодом создает несвязанные внучатые ключи
  • При изменении кода цепочки создается новый узел
  • Из расширенного закрытого ключа мы можем сгенерировать как дочерние закрытые, так и открытые ключи, то есть создать полный кошелек
  • Из расширенного открытого ключа мы можем создать только дочерние открытые ключи, которые могут быть полезны только для генерации адресов
+-----------+------------+----------+
| from \ to | private    | public   |
+-----------+------------+----------+
| private   | possible   | possible |
+-----------+------------+----------+
| public    | impossible | possible |
+-----------+------------+----------+

Эти правила могут быть реализованы следующим образом:

Резюме

Эта статья завершает серию сообщений о создании автономного биткойн-кошелька кошелек в Elixir.

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

Если вас интересует весь проект, он доступен прямо здесь:



Там вы найдете полезные примеры и соответствующий набор тестов. Наслаждаться!