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

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

Публичен ключ

Публичен ключ биткойн: как се получава от частния ключ върху кривата secp256k1, както и компресираната, некомпресираната и x-only формата.

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

Публичният ключ в биткойн (bitcoin) се получава, като умножите фиксирана точка от кривата secp256k1 по частния ключ. Резултатът е точка от същата крива. Тя е публичната половина на двойката, затова може безопасно да се споделя. Монетите могат да се заключат към публичен ключ, а само съответният частен ключ ги отключва. Биткойн записва публичния ключ като шестнадесетичен низ в една от трите форми: компресирана, некомпресирана или x-only.

Как се получава публичен ключ?

Публичният ключ се получава чрез умножение върху елиптичната крива. Кривата има фиксирана начална точка, наречена генераторна точка, G. Умножавате G по частния ключ, число от 1 до n-1, и резултатът е нова точка от кривата. Тази точка е публичният ключ. Умножението е бързо. Обратното, от точката към частния ключ, няма известен практичен метод. Страницата за елиптичната крива разглежда математиката.

Параметрите на secp256k1 са публикувани в SEC 2. Този кратък скрипт умножава G по частен ключ, без да ползва библиотека. Той е бавен, затова е само за учене. Истинският код трябва да ползва тествана библиотека.

# простото число на полето secp256k1 и генераторната точка
P = 2**256 - 2**32 - 977
G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
     0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

def add(a, b):
    if a is None: return b
    if b is None: return a
    if a[0] == b[0] and (a[1] + b[1]) % P == 0: return None
    if a == b: s = 3 * a[0] * a[0] * pow(2 * a[1], -1, P) % P
    else: s = (b[1] - a[1]) * pow(b[0] - a[0], -1, P) % P
    x = (s * s - a[0] - b[0]) % P
    return (x, (s * (a[0] - x) - a[1]) % P)

def public_key(k):
    """Умножава генераторната точка G по частния ключ k."""
    point, result = G, None
    while k:
        if k & 1: result = add(result, point)
        point = add(point, point)
        k >>= 1
    return result

k = int("dbf34ebb797c7b62960c0c7d1784c3209d5de7abf307df4a07dac9c76f22ee72", 16)
x, y = public_key(k)
prefix = "02" if y % 2 == 0 else "03"
print(prefix + f"{x:064x}")  # 02cd33111c7fc75b33bc30ad959dd27433d631dee5bf072733334163dedc403070

Примерният ключ е този от страницата за частния ключ. Компресираният му публичен ключ е 02cd33111c7fc75b33bc30ad959dd27433d631dee5bf072733334163dedc403070. Не ползвайте този ключ с истински монети, защото всеки може да го види.

Какви са трите форми на публичен ключ?

Един публичен ключ в три форми: компресиран ключ от 33 байта, некомпресиран от 65 байта и x-only ключ от 32 байта. Компресиран: 33 байта Стандартният. Префикс 02 или 03, после x. 02 или 03 x: 32 байта 02cd33111c…dedc403070 Некомпресиран: 65 байта Стар формат, още валиден. 04 x: 32 байта y: 32 байта 04cd33111c…ea9c198538 x-only: 32 байта Taproot, BIP 340. Без префикс, затова y е четно. x: 32 байта cd33111c7f…dedc403070
Същата точка, записана по три начина. Компресираният е стандартният днес.

Всяка форма започва със същата координата x, 32-байтово число. Формите се различават по това, което добавят към нея. Компресираният ключ добавя байт с префикс, който записва четността на y. Некомпресираният ключ добавя цялата координата y. Ключът x-only не добавя нищо.

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

Компресираният публичен ключ е 33 байта. Той съдържа цялата координата x и префикс, който показва дали y е четно или нечетно. Префиксът е 02, когато y е четно, и 03, когато y е нечетно.

Кривата е симетрична, затова за всяко x, което лежи на кривата, има само две възможни стойности на y. Те са с различна четност: едното е четно, а другото нечетно. Префиксът е достатъчен, за да се избере правилното, затова ключът пази префикса, а не цялото y. Примерният ключ има четно y, значи префиксът му е 02.

Използвайте компресирани ключове по подразбиране. Те са по-къси, а политиката по подразбиране на Bitcoin Core отхвърля некомпресираните ключове в SegWit v0 скриптове, като P2WPKH и P2WSH. По подразбиране такива трансакции не се препращат между нодовете и не се включват в блок. Проверката е флагът SCRIPT_VERIFY_WITNESS_PUBKEYTYPE в интерпретатора на скриптове на Bitcoin Core. BIP 143 задава същото правило.

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

Некомпресираният публичен ключ е 65 байта. Започва с 04, следвано от цялата 32-байтова координата x и цялата 32-байтова координата y. Ранният софтуер е използвал тази форма, преди компресираните ключове да се наложат. Примерният ключ в некомпресирана форма е:

04cd33111c7fc75b33bc30ad959dd27433d631dee5bf072733334163dedc403070002efe73430d2af79531c7d8f64500b5c392db9af29ccfd60e2ca7ea9c198538

Некомпресираните ключове все още работят в стари (legacy) заключващи скриптове, като P2PK, P2PKH, P2SH и голи мултиподписи (bare multisig). Политиката по подразбиране ги отхвърля в P2WPKH и P2WSH изходи. Затова днес няма голяма причина да ги избирате.

Какво е x-only публичен ключ?

x-only публичният ключ е 32-байтовата координата x без префикс. Taproot ползва тази форма, описана в BIP 340. Тъй като няма префикс, ключът се приема за четно y. Всяка точка с нечетно y може да се замени с партньора ѝ с четно y, затова трябва да се пази само x.

Примерният ключ има четно y, така че неговата x-only форма е компресираният ключ без префикса 02: cd33111c7fc75b33bc30ad959dd27433d631dee5bf072733334163dedc403070. Изход в Taproot се заключва към преработена (tweaked) версия на този ключ. Страницата за Taproot обяснява ъпгрейда, който е в сила от блок 709,632.

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

Можете да възстановите пълния некомпресиран ключ от компресирания. Кривата secp256k1 следва уравнението y² = x³ + 7, по модул p, простото число, спрямо което работят изчисленията. Знаете x, затова търсите y. Отговорът е квадратен корен с две стойности, едната четна и другата нечетна. Префиксът показва коя да запазите.

Тъй като p е 3 по модул 4, квадратният корен се смята с едно степенуване. Кратката програма по-долу възстановява некомпресирания ключ от компресирания.

P = 2**256 - 2**32 - 977

compressed = "02cd33111c7fc75b33bc30ad959dd27433d631dee5bf072733334163dedc403070"
x = int(compressed[2:], 16)

# y^2 = x^3 + 7 (mod P); P е 3 по модул 4, така че квадратният корен е едно степенуване
y = pow((x**3 + 7) % P, (P + 1) // 4, P)

# префиксът показва дали y трябва да е четно (02) или нечетно (03)
if (y % 2 == 0) != (compressed[:2] == "02"):
    y = P - y

print("04" + f"{x:064x}" + f"{y:064x}")
Декомпресиране: префиксът избира четния или нечетния корен на уравнението на кривата и така се получава некомпресираният ключ. Начало: компресираният ключ 02cd33111c…dedc403070 y² = x³ + 7 (mod p) Решаваме за y два корена: единият четен, другият нечетен Четно y: пазим 002efe73…9c198538 избира префикс 02 Нечетно ffd1018c…63e676f7 отпада при 02 Некомпресиран ключ: 65 байта 04cd33111c…ea9c198538 04, после x, после четното y
Четният корен е y на примерния ключ. Нечетният корен е другата точка със същото x.

Къде се появяват публичните ключове в блокчейна?

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

Заключващ скрипт Къде стои публичният ключ Реален пример
P2PK Записан цял в scriptPubKey, затова е публичен още щом монетите пристигнат 18a16d32…ee444, coinbase изход в блок 150,007
P2PKH В заключването стои само хешът. Целият ключ се показва в scriptSig, когато похарчите faf2987f…0808c, която харчи P2PKH изход в блок 770,002
P2WPKH В заключването стои само хешът. Ключът е в witness, когато похарчите 1674761a…4a6, която харчи P2WPKH изход в блок 682,085

P2PK е най-простото заключване, но показва ключа от самото начало. P2PKH и P2WPKH скриват ключа зад хеш, докато не похарчите. Taproot изходът е различен: той показва от самото начало преработена версия на ключа, а не ключа, който държите.

Как публичният ключ получава монети?

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

Повечето портфейли ви показват адрес, а не суровия ключ, защото адресът е по-къс и по-лесен за копиране. Адресът се строи от хеша на публичния ключ, а за него е следващата страница в раздела.

Кой ключ да ползвате?

Частният ключ пазете в тайна. Публичният ключ е частта, която можете да публикувате. За старите изходи и за SegWit v0 ползвайте компресирани ключове, които са по 33 байта. Taproot ползва x-only формата на същата точка, тоест компресирания ключ без префикса.

Следващата страница, хеш на публичния ключ, показва как този ключ се хешира в стойността, която носят повечето адреси.

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

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

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