Как получить закрытый ключ, связанный с адресом хранилища Coinbase с несколькими подписями

Когда я создал мультиподписное хранилище на Coinbase, я получил:

  1. Главный открытый ключ в расширенном формате BIP32 с глубиной 0, родительским отпечатком 00000000и дочерним индексом 0.
  2. Закрытый ключ в формате WIF («пользовательское начальное число»), который я не знаю, был ли он усилен, получен из открытого ключа, глубины или индекса.

Я пытаюсь доказать право собственности на адрес, полученный из главного открытого ключа по индексу 14. Таким образом, используя bip32.org , я смог получить открытый ключ в расширенном формате BIP32 по индексу m/14, который точно соответствует адресу, для которого мне нужно подтвердить право собственности.

Поэтому моя цель теперь состоит в том, чтобы получить закрытый ключ, адрес которого совпадает с адресом производного открытого ключа в индексе m/14, на основе имеющейся у меня информации. Если можно с pybitcointools.

Я попытался задать более общий вопрос здесь , но это был хороший случай проблемы XY (я спросил о своей попытке решения, а не о реальной проблеме).

Не могли бы вы опубликовать пример xpub/WIF/сгенерированного адреса? Это помогло бы мне понять, чего они от тебя хотят. (Очевидно, не тот, который вы используете для работы с реальными деньгами.)

Ответы (1)

Я немного покопался в автономном инструменте мультиподписи Coinbase, чтобы выяснить, что на самом деле представляло собой пользовательское семя, и пути их получения. Оказывается, пользовательское семя — это просто семя, которое используется для получения мастер-закрытого ключа. Это делается путем хеширования с помощью HMAC-SHA512, где ключ — это строка Bitcoin seed, а данные — двоичная форма пользовательского начального числа (что означает его декодирование и получение двоичных данных).

Чтобы сделать это с помощью pybitcointools, мы сначала декодируем начальное значение пользователя WIF с помощью decode_privkeyи перекодируем его с помощью encode_privkey, чтобы получить двоичную форму. Затем мы передаем это, bip32_master_keyчтобы получить мастер-ключ bip32 из этого семени. И оттуда просто позвоните, bip32_ckdчтобы получить расширенный закрытый ключ любого дочернего элемента индекса, который мы хотим. Наконец, мы извлекаем фактический закрытый ключ с помощью bip32_bin_extract_keyи кодируем его с помощью encode_privkey, чтобы получить его в форме WIF, которую можно импортировать и использовать в другом программном обеспечении кошелька.

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

Замените значения для USER_PUB, USER_SEED и I фактическим открытым ключом пользователя, начальным числом пользователя и дочерним индексом, которые вы хотите. Ценности, которые у меня есть здесь, реальны и будут работать.

from pybitcointools.deterministic import bip32_ckd, bip32_master_key, bip32_bin_extract_key, bip32_privtopub
from pybitcointools.main import decode_privkey, encode_privkey

USER_PUB = 'xpub661MyMwAqRbcEzdGMFKZXuVwbyHY2zKhiw6YFTrULfNBF53QVfXyoAiKMZKWkQA5444NXtLj9HPmgyN1xLCiJJ9dKAy4nLZJ87trHRnwUDb'
USER_SEED = 'L3XCYcQ2pwY3YTuwyPXzWsvVtGnCp4zL2ajP3XQt2pVhPuKiVM7r'
I = 14

user_seed = encode_privkey(decode_privkey(USER_SEED), 'bin')
priv = bip32_master_key(user_seed)
derived_pub = bip32_privtopub(priv)
child_priv = bip32_ckd(priv, I)
assert USER_PUB == derived_pub
print "Master Private Key corresponding to seed: " + priv
print "Master Public Key corresponding to seed: " + derived_pub
print "Extended Private key at index " + str(I) + ": " + child_priv
print "WIF format of that key: " + encode_privkey(bip32_bin_extract_key(child_priv), 'wif_compressed')
Отлично, это работает отлично!