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

У першій частині цієї серії статей, ми зробили Bitcoin закритого ключа: 60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2.

Тут ми використаємо цей ключ, щоб отримати публічну адресу, а потім адресу гаманця Ethereum цього закритого ключа.

Створення адреси біткойн-гаманця з приватного ключа дещо складне. Тут процес буде набагато простішим. Нам потрібно застосувати одну хеш-функцію, щоб отримати відкритий ключ, а іншу - отримати адресу.

Тож давайте почнемо.

Відкритий ключ

Ця частина майже ідентична тому, що ми обговорювали в статті про біткойни, тому, якщо ви прочитаєте її, ви можете пропустити її (якщо вам не потрібне оновлення).

Перше, що нам потрібно зробити, це застосувати ECDSA, або алгоритм цифрового підпису еліптичної кривої, до нашого приватного ключа. Еліптична крива - це крива, яка визначається рівнянням y² = x³ + ax + bіз вибраним aі b. Існує ціле сімейство таких кривих, які широко відомі і використовуються. Біткойн використовує криву secp256k1 . Якщо ви хочете дізнатися більше про криптографічну криптографічну криву, я перейду до цієї статті.

Ethereum використовує одну і ту ж еліптичну криву, secp256k1 , тому процес отримання відкритого ключа ідентичний в обох криптовалютах.

Застосовуючи ECDSA до приватного ключа, ми отримуємо 64-байтове ціле число, яке є двома 32-байтовими цілими числами, які представляють X і Y точки на еліптичній кривій, об'єднані разом.

Для нашого прикладу ми отримали 1e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7b73ff919898c836396a6b0c96812c3213b99372050853bd1678da0ead14487d7.

У Python це буде виглядати так:

private_key_bytes = codecs.decode(private_key, ‘hex’) # Get ECDSA public key key = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1).verifying_key key_bytes = key.to_string() key_hex = codecs.encode(key_bytes, ‘hex’)

Примітка: як ви можете бачити з коду вище, я використав метод із ecdsaмодуля і розшифрував закритий ключ за допомогою codecs. Це більше стосується Python і менше самого алгоритму, але я поясню, що ми робимо тут, щоб усунути можливу плутанину.

У Python існує принаймні два класи, які можуть зберігати приватний та відкритий ключі: “str” та “bytes”. Перший - це рядок, а другий - байтовий масив. Криптографічні методи в Python працюють з класом “bytes”, беручи його як вхідні дані та повертаючи як результат.

Тепер є невелика фішка: рядок, скажімо, 4f3cне дорівнює масиву байтів 4f3c. Швидше, це дорівнює байтовому масиву з двома елементами, O&lt ;. І ось що he codecs.decробить метод t ode: він перетворює рядок у байтовий масив. Це буде однаковим для всіх криптографічних маніпуляцій, які ми будемо робити в цій статті.

Адреса гаманця

Отримавши відкритий ключ, ми можемо розрахувати адресу. Зараз, на відміну від біткойнів, Ethereum має однакові адреси як в основній, так і у всіх тестових мережах. Користувачі вказують мережу, яку вони хочуть використовувати пізніше в процесі, коли вони роблять та підписують транзакцію.

Щоб зробити адресу з відкритого ключа, все, що нам потрібно зробити, це застосувати Keccak-256 до ключа, а потім взяти останні 20 байт результату. І це все. Жодних інших хеш-функцій, жодного Base58 чи будь-якого іншого перетворення. Єдине, що вам потрібно, це додати '0x' на початку адреси.

Ось код Python:

public_key_bytes = codecs.decode(public_key, ‘hex’) keccak_hash = keccak.new(digest_bits=256) keccak_hash.update(public_key_bytes) keccak_digest = keccak_hash.hexdigest() # Take the last 20 bytes wallet_len = 40 wallet = ‘0x’ + keccak_digest[-wallet_len:]

Контрольна сума

Тепер, як ви пам'ятаєте, біткойн створює контрольну суму шляхом хешування відкритого ключа і беручи перші 4 байти результату. Це справедливо для всіх біткойн-адрес, тому ви не можете отримати дійсну адресу, не додавши контрольні суми байтів.

В Ефіріумі все не так працює. Спочатку не існувало механізмів контрольної суми для перевірки цілісності ключа. Однак у 2016 році Віталік Бутерін запровадив механізм контрольної суми, який з тих пір був прийнятий гаманцями та біржами.

Додавання контрольної суми до адреси гаманця Ethereum робить її чутливою до регістру.

По-перше, вам потрібно отримати хеш адреси Keccak-256. Зверніть увагу, що цю адресу слід передавати хеш-функції без 0xчастини.

По-друге, ви перебираєте символи початкової адреси. Якщо i- й байт хешу більший або дорівнює 8, ви перетворюєте символ i- ї адреси у верхній регістр, інакше ви залишаєте його в нижньому регістрі.

Нарешті, ви додаєте 0xназад на початку отриманого рядка. Адреса контрольної суми така ж, як і початкова, якщо ви ігноруєте справу. Але великі літери дозволяють будь-кому перевірити, чи дійсно адреса дійсна. Ви можете знайти алгоритм перевірки контрольної суми на сторінці, на яку посилається тут.

Як ви прочитаєте в пропозиції, для цієї схеми контрольної суми,

"В середньому буде 15 контрольних бітів на адресу, а чиста ймовірність того, що випадково згенерована адреса при помилковому введенні випадково пройде перевірку, становить 0,0247%."

І ось код для додавання контрольної суми до адреси Ethereum:

checksum = ‘0x’ # Remove ‘0x’ from the address address = address[2:] address_byte_array = address.encode(‘utf-8’) keccak_hash = keccak.new(digest_bits=256) keccak_hash.update(address_byte_array) keccak_digest = keccak_hash.hexdigest() for i in range(len(address)): address_char = address[i] keccak_char = keccak_digest[i] if int(keccak_char, 16) >= 8: checksum += address_char.upper() else: checksum += str(address_char)

Висновок

Як бачите, створення адреси для Ethereum набагато простіше, ніж для біткойнів. Все, що нам потрібно зробити, це застосувати ECDSA до відкритого ключа, потім застосувати Keccak-256 і, нарешті, взяти останні 20 байт цього хешу.

Якщо ви хочете пограти з кодом, я опублікував його у сховищі GitHub.

Я читаю курс криптовалют тут, на FreeCodeCamp News. Перша частина - це детальний опис блокчейну.

Я також публікую випадкові думки щодо криптографії в Twitter, тож ви можете перевірити це.