Към съдържанието
ДаретеEN

Ключове и адреси

Разширени ключове

xpub биткойн е разширен публичен ключ: публичен ключ с chain code, който създава дъщерни ключове. Вижте как се строят xpub и xprv и какви са рисковете.

От Dimitar Zurnov · Обновено на 4 ноември 2026
Адаптирано от Learn Me a Bitcoin на Greg Walker.

xpub е разширен публичен ключ: публичен ключ, свързан с 32-байтов chain code, така че може да създава дъщерни ключове. Разширеният ключ е тази двойка, частна или публична, и е единицата, която HD портфейлът предава надолу по дървото. Разширеният частен ключ, записан xprv, създава както частни, така и публични деца. Разширеният публичен ключ, записан xpub, създава само нормални публични деца.

И двете форми се записват като низ в Base58Check, затова започват с фиксирани префикси и са дълги до 111 знака. Тези низове портфейлите импортират, експортират и споделят.

Какво има в разширения ключ?

Разширеният ключ е 78 байта полета плюс 4-байтова контролна сума. Полетата записват къде стои ключът в дървото, а последното поле съдържа самия ключ.

Поле Размер Какво съдържа
Версия 4 байта Префиксът, например 0488ade4 за xprv
Дълбочина 1 байт Колко стъпки под главния ключ е ключът. За главния е 0.
Отпечатък на родителя 4 байта Първите 4 байта от HASH160 на публичния ключ на родителя, или 00000000 за главния
Номер на дете 4 байта Индексът на този ключ под родителя, или 00000000 за главния
Chain code 32 байта Тайната, която прави децата непредсказуеми
Ключ 33 байта Частният ключ с байт 00 отпред, или компресираният публичен ключ

Частният ключ е 32 байта, така че байтът 00 го прави 33, същата дължина като компресиран публичен ключ. И двете форми се сериализират по един и същ начин.

Разширеният ключ е 78 байта полета, плюс 4-байтова контролна сума, записан в Base58 като 111 знака. версия, 4 байта 0488ade4 (xprv) дълбочина, 1 байт 01 (една стъпка под главния) отпечатък на родителя, 4 байта 3442193e номер на дете, 4 байта 80000000 (индекс 2^31, значи 0') chain code, 32 байта 47fdacbd0f1097043b78c63c20c34ef4 ed9a111d980047ad16282c7ae6236141 ключ, 33 байта 00 + 32-байтовият частен ключ: edb2e14f9ee77d26dd93b4ecede8d16e d408ce149b6cd80b0715a2d911a0afea 78 байта до тук, после 4-байтова контролна сума. Base58 кодиране, 111 знака xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDi PvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesn DYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7
Примерът е m/0' от тестов вектор 1 на BIP 32, публичен тестов вектор. Отпечатъкът му е този на главния ключ, а номерът на дете 80000000 означава индекс 2^31.

Отпечатъкът и номерът на дете не влияят на аритметиката. Те само показват мястото на ключа, така че софтуерът да свърже дете с родителя си, без да търси в цялото дърво. Четирибайтовият номер на дете е и причината разширен ключ да има най-много 4,294,967,296 деца.

Кои версийни байтове какво означават?

Версийните байтове казват на софтуера какъв вид е ключът и кой вид портфейл го ползва. Ето най-често срещаните.

Префикс Версийни байтове За какво се ползва
xprv 0488ade4 Разширен частен ключ, BIP 32
xpub 0488b21e Разширен публичен ключ, BIP 32
yprv 049d7878 Разширен частен ключ, BIP 49 (вложен SegWit)
ypub 049d7cb2 Разширен публичен ключ, BIP 49
zprv 04b2430c Разширен частен ключ, BIP 84 (роден SegWit)
zpub 04b24746 Разширен публичен ключ, BIP 84

Префиксите y и z променят само версийните байтове. Ключът и chain code вътре са от същия вид като при xprv или xpub. Taproot, в BIP 86, няма собствен префикс. Неговите ключове ползват xprv и xpub, а типът скрипт се посочва на друго място. Bitcoin Core ползва output descriptors, за да каже за кой тип скрипт служи даден ключ.

Какъв е главният разширен ключ?

Главният ключ идва направо от сийда. HMAC-SHA512 с ключ Bitcoin seed се разделя на главен частен ключ и chain code, както показва страницата за HD портфейлите. Главният ключ има дълбочина 0, нулев отпечатък и нулев номер на дете.

За тестов вектор 1 на BIP 32 главният разширен частен ключ е:

xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi

Неговият разширен публичен ключ е:

xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8

И двата са публикувани в BIP-а, така че са безопасни за копиране при тестване. Никога не ги ползвайте с монети.

Как се създава нормален дъщерен частен ключ?

Нормалното дете има индекс от 0 до 2,147,483,647. Публичният ключ на родителя се подава в HMAC заедно с индекса. Който има xpub на родителя, може да изчисли тази корекция (tweak), но само частният ключ може да довърши частния ключ на детето. Ето стъпките.

  1. Вземете компресирания публичен ключ на родителя, 33 байта, и добавете индекса като 4 байта, big-endian.
  2. Изпълнете HMAC-SHA512 върху тези данни, като за ключ ползвате chain code на родителя.
  3. Разделете 64-байтовия изход. Лявите 32 байта са IL, а дясните 32 байта са chain code на детето.
  4. Добавете IL към частния ключ на родителя и редуцирайте сбора по модул n, реда на кривата. Резултатът е частният ключ на детето.

За m/0'/1, детето на първия hardened ключ на тестовия вектор, тези стъпки дават частния ключ 3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368. Публичният му ключ е 03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c.

Как се създава нормален дъщерен публичен ключ?

Публичният път ползва същия IL и същия chain code, но работи върху точки, а не върху числа. Публичният ключ е точката от кривата на своя частен ключ, така че прибавянето на IL към частния ключ означава прибавяне на IL пъти генераторната точка към публичния ключ. Публичният път изчислява IL × G и го прибавя към публичния ключ на родителя. Резултатът е публичният ключ от частния път.

Затова xpub може да създава публични ключове без частния ключ. Кодът по-долу извършва двата пътя и извежда и двата резултата. Те трябва да съвпаднат. Аритметиката е същата като при частния път, но работата се върши от публичния ключ.

import hashlib, hmac, struct

N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141  # order of the curve
P = 2**256 - 2**32 - 977
G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
     0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

def add(p, q):                       # point addition on secp256k1
    if p is None: return q
    if q is None: return p
    if p[0] == q[0] and (p[1] + q[1]) % P == 0: return None
    if p == q: s = 3 * p[0] * p[0] * pow(2 * p[1], -1, P) % P
    else: s = (q[1] - p[1]) * pow(q[0] - p[0], -1, P) % P
    x = (s * s - p[0] - q[0]) % P
    return x, (s * (p[0] - x) - p[1]) % P

def mul(k, pt=G):                    # scalar multiplication
    r = None
    while k:
        if k & 1: r = add(r, pt)
        pt = add(pt, pt)
        k >>= 1
    return r

def compress(pt):                    # 33-byte compressed public key
    return bytes([2 + pt[1] % 2]) + pt[0].to_bytes(32, "big")

def tweak(parent_pub, chain, index):
    # IL and the child chain code, from HMAC-SHA512 of the parent public key and index
    I = hmac.new(chain, parent_pub + struct.pack(">I", index), hashlib.sha512).digest()
    return int.from_bytes(I[:32], "big"), I[32:]

# parent m/0' from BIP 32 test vector 1
parent_priv = 0xedb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea
parent_chain = bytes.fromhex("47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141")
parent_point = mul(parent_priv)      # the parent public key
il, child_chain = tweak(compress(parent_point), parent_chain, 1)

child_priv = (il + parent_priv) % N          # private route: needs the private key
child_point = add(mul(il), parent_point)     # public route: needs only the xpub

print(child_priv.to_bytes(32, "big").hex())  # 3c6cb8d0...
print(compress(child_point).hex())           # 03501e45...

Стартирайте кода, за да получите двете стойности от коментарите. Проверете публичния ключ спрямо частния, преди да разчитате на кода.

Как се създава hardened дете?

Hardened детето има индекс от 2,147,483,648 до 4,294,967,295. Входът му за HMAC ползва частния ключ на родителя, а не публичния. Данните са 00, после 32-байтовият частен ключ, после 4-байтовият индекс, общо 37 байта. Останалото е същото: лявата половина от HMAC се добавя към ключа на родителя, а дясната е chain code.

Нормалното дете хешира публичния ключ на родителя, а hardened детето частния ключ. И двете прибавят лявата половина към ключа на родителя. нормално дете, индекс под 2^31 HMAC данни: публичен ключ на родителя (33 байта) || индекс (4 байта) HMAC ключ: chain code на родителя IL = лявите 32 байта от изхода ключ на детето = IL + ключ, mod n chain code = дясните 32 байта hardened дете, индекс от 2^31 HMAC данни: 00 || частният ключ на родителя (32 байта) || индекс (4 байта) HMAC ключ: chain code на родителя IL и chain code както по-горе ключ на детето = IL + ключ, mod n
Hardened деривацията изисква частния ключ, така че xpub не може да създаде hardened дете.

Първото hardened дете на главния ключ, m/0', е примерът от диаграмата с разположението по-горе. Частният му ключ е edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea, който портфейлът би ползвал за подписване на този клон.

Тъй като входът съдържа частния ключ, никой публичен ключ не може да създаде hardened дете. В това е смисълът на hardened деривацията. Публичният ключ на hardened дете не може да бъде изведен от никого, който има само xpub на родителя.

Каква е слабостта на нормалните деца?

Частният ключ на нормалното дете е частният ключ на родителя плюс стойността IL, която всеки с xpub на родителя може да изчисли. Така че ако някой има xpub на родителя и частния ключ на едно нормално дете, може да извади IL и да възстанови частния ключ на родителя:

parent private key = child private key - IL

Публичният ключ и chain code на родителя, които са в xpub, стигат, за да се изчисли IL при всеки индекс. Така се разкрива родителят и всяко нормално дете под него. Можете да проверите тази стъпка с кода по-горе: (child_priv - il) % N връща parent_priv.

От това следват две правила. Никога не разкривайте частния ключ на нормално дете, докато xpub на родителя е публичен. И ползвайте hardened деца на нивото, където започва акаунтът, за да не стигне изтичане по-долу до ключа на акаунта. Пътищата за деривация показват къде е това ниво.

Разширените ключове адреси ли са?

Не. Думата „адрес“ се появява в менюта на някои портфейли, но xpub не е нещо, на което можете да платите. Той е ключ, който създава много ключове. За да получи монети, портфейлът взема xpub, извежда дете и строи платим адрес от публичния ключ или от скрипта на детето. Страницата за адресите обяснява типовете.

Какво да запомните за разширените ключове?

  • Разширеният ключ е ключ плюс chain code, сериализиран в 78 байта и записан в Base58Check.
  • xprv създава частни и публични деца, а xpub създава само нормални публични деца.
  • Префиксите y и z променят само версийните байтове, не начина на деривация.
  • Частният ключ на нормално дете заедно с xpub на родителя разкрива родителя. Hardened децата предотвратяват това.

Следващо прочетете пътищата за деривация, за да видите как портфейлът записва един ключ в дървото, например m/84'/0'/0'/0/0.

В този раздел: Ключове и адреси

Целият курс „Биткойн от нулата“

Нещо не изглежда наред? Кажете ни