Понимание концепции закрытого ключа, открытого ключа и адреса в блокчейне Ethereum
Внимание! Это техническая статья, рассчитанная на блокчейн специалистов и объясняет как генерируются ключи внутри блокчейна.
Если Вам нужна помощь в открытии и сохранении своих приватных ключей, то обратитесь к статье: Как установить холодный кошелек Ethereum
Прежде чем мы углубимся в концепцию блокчейна Ethereum, важно понять, как генерируются открытый ключ, закрытый ключ и адрес.
Чтобы сделать это проще для начинающих, мы попытаемся объяснить техническую концепцию на простом примере.
Простой пример
Закрытый ключ (секретный большой номер) создается вашим кошельком случайным образом, затем шифруется (с вашим паролем) и сохраняется в файле UTC в папке хранилища ключей. В тоже время ваш публичный адрес рассчитывается на основе открытого ключа, полученного из закрытого.
Это было просто определение. Теперь рассмотрим как это работает.
Генерация ключей в Ethereum
Генерация ключа Ethereum основана на эллиптической кривой ecp256k1
.
Эллиптическая кривая - это сложная математика, и в интернете есть много замечательных статей, в которых подробно рассматриваются эллиптические кривые (например в вики).
Существуют стандартные библиотеки для генерации пары ключей Ethereum более безопасным способом. В этой статье, просто для демонстрации, мы будем использовать библиотеку Javascript для выполнения операций с эллиптической кривой.
Закрытый ключ (Private Key)
В эллиптической кривой cp256k1
любое число от 1 до 2 ^ 256-1 является допустимым закрытым ключом.
Хорошая библиотека генерирует закрытый ключ с учетом необходимой случайности. Для этого упражнения мы возьмем «1» в качестве закрытого ключа, который является допустимым закрытым ключом, поскольку он находится в указанном диапазоне, указанном выше. Ethereum требует, чтобы закрытый ключ был длиной в 256 бит. Вот пример кода для nodejs.
var privateKey=Buffer.alloc(32, 0); privateKey[31]=1; console.log("PK::"+privateKey.toString('hex'))
Это отобразит закрытый ключ в шестнадцатеричном виде, который
PK::0000000000000000000000000000000000000000000000000000000000000001
Открытый ключ (Public key)
Открытый ключ описывается следующим образом в желтой бумаге Эфириума.
«Где pu - открытый ключ, предполагается, что это байтовый массив размером 64 (сформированный из конкатенации двух положительных целых чисел каждое <2256), а pr - закрытый ключ, байтовый массив размером 32 (или одно целое положительное число в указанном диапазоне).»
Это достигается с помощью групповой операции эллиптической кривой в криптографии.
Для получения открытого ключа закрытый ключ умножается на G. Умножение, используемое для получения открытого ключа, является умножением эллиптической кривой, которое полностью отличается от обычного умножения, для которого мы собираемся использовать библиотеку JS.
G называется точкой генератора, которая является одним из ключевых параметров криптографии эллиптической кривой. G имеет фиксированное значение для ecp256k1
, которое рекомендуется экспертами. Вы можете прочитать больше здесь.
var EC = require('elliptic').ec; var BN = require('bn.js'); var ec = new EC('secp256k1'); var G = ec.g; // Generator point var pk = new BN('1'); // private key as big number var pubPoint=G.mul(pk); // EC multiplication to determine public point var x = pubPoint.getX().toBuffer(); //32 bit x co-ordinate of public point var y = pubPoint.getY().toBuffer(); //32 bit y co-ordinate of public point var publicKey =Buffer.concat([x,y]) console.log("pub key::"+publicKey.toString('hex'))
Адрес Эфириума (Ethereum Address)
Адрес Ethereum описывается следующим образом в желтой бумаге:
«Для данного закрытого ключа, pr, адрес Ethereum a (pr) (160-битное значение), которому он соответствует, определяется как самый правый 160-битный хэш Keccak соответствующего открытого ключа ECDSA.»
Чтобы сгенерировать адрес Ethereum, возьмите хеш открытого ключа Keccak-256. Самые правые 20 байт - это и есть ваш адрес Ethereum.
var EC = require('elliptic').ec; var BN = require('bn.js'); var ec = new EC('secp256k1'); const keccak256 = require('js-sha3').keccak256; var privateKey=Buffer.alloc(32, 0); privateKey[31]=1; console.log("PK::"+privateKey.toString('hex')) var G = ec.g; // Generator point var pk = new BN('1'); // private key as big number var pubPoint=G.mul(pk); // EC multiplication to determine public point var x = pubPoint.getX().toBuffer(); //32 bit x co-ordinate of public point var y = pubPoint.getY().toBuffer(); //32 bit y co-ordinate of public point var publicKey =Buffer.concat([x,y]) console.log("public key::"+publicKey.toString('hex')) const address = keccak256(publicKey) // keccak256 hash of publicKey const buf2 = Buffer.from(address, 'hex'); console.log("Ethereum Adress:::"+"0x"+buf2.slice(-20).toString('hex')) // take lat 20 bytes as ethereum adress
PK:: 0000000000000000000000000000000000000000000000000000000000000001
Адрес Ethereum::: 0x7e5f4552091a69125d5dfcb7b8c2659029395bdf
Это всего лишь пример, чтобы понять концепцию. Пожалуйста, не используйте его для создания реального кошелька для хранения ETH.
Если вы найдете эту статью полезной, вы можете оказать свою признательность, поделившись ею.