Главная » Статьи » Как создать собственную криптовалюту с помощью JavaScript

Как создать собственную криптовалюту с помощью JavaScript

Как создать собственную криптовалюту с помощью JavaScript

От автора: в настоящее время существует множество способов отправить деньги кому-то в цифровом виде. Большинство способов — через банк или через онлайн кошельки, но в последнее время стало популярным использование криптовалюты.

Криптовалюта — отличный способ анонимно отправлять деньги другим людям. Еще одним преимуществом криптовалют является то, что их сеть децентрализована, а это означает, что никто не контролирует транзакцию и нет посредников. Одни люди думают, что это плохо, потому что большинство мошенников работают с криптовалютами, но для других — это очередной шаг к конфиденциальности.

Сегодня мы собираемся создать криптовалюту с помощью JavaScript. Надеюсь, эта статья даст вам общее представление о том, как создать собственную криптовалюту, и вы сможете продолжить работу над этими навыками для улучшения конфиденциальности своих финансов.

Требования:

Node.js установлен на вашем компьютере

Редактор кода (я предпочитаю Visual Studio Code)

Практическое знание Node

Вы всегда можете обратиться к репозиторию GitHub, если хотите взглянуть на код.

Давайте начнем с создания проекта Node. Перейдите в безопасный каталог и введите следующую команду, чтобы создать новый проект:

npm init -y

Это должно сгенерировать файл package.json. Если файл создан, значит, создался и проект.

Теперь давайте создадим новый файл с именем index.js. Сначала импортируйте crypto пакет, чтобы мы могли иметь дело с хешами в проекте. Пакет crypto помогает нам работать с хешами, подписями и ключами. Он позволяет выполнять криптографическое преобразование в Node.

Это предустановленный пакет с Node, поэтому вам не нужно устанавливать его отдельно:

const crypto = require("crypto");

Мы будем иметь дело с четырьмя классами. Их названия:

Transaction

Block

Chain

Wallet

Сначала давайте создадим класс Transaction.

Создание класса Transaction

Основными свойствами транзакции будут amount, senderPublicKey и recieverPublicKey. Итак, давайте настроим конструктор, чтобы мы могли использовать этот класс позже:

class Transaction { constructor(amount, senderPublicKey, recieverPublicKey) { this.amount = amount; this.senderPublicKey = senderPublicKey; this.recieverPublicKey = recieverPublicKey; }
}

Нам также нужен метод для преобразования объекта класса в строку, чтобы преобразовать ее в хеш. Итак, создадим функцию для преобразования объекта в строку для дальнейшего использования:

toString() { return JSON.stringify(this);
}

Ваш полный класс Transaction должен выглядеть следующим образом:

class Transaction { constructor(amount, senderPublicKey, recieverPublicKey) { this.amount = amount; this.senderPublicKey = senderPublicKey; this.recieverPublicKey = recieverPublicKey; } // convert the data of the class to json so that // it can be converted into a hash toString() { return JSON.stringify(this); }
}

Теперь мы можем хранить транзакции внутри блока, который создадим следующим.

Создание класса Block

Термин «блокчейн» означает именно то, что он звучит — цепочку блоков. Цепочка — это набор блоков (содержащих транзакции), связанных друг с другом, чтобы мы могли получить к ним систематический доступ. Для начала давайте настроим конструкторы и свойства, которые будем использовать в классе Block:

class Block { constructor(previousHash, transaction, timestamp = Date.now()) { this.previousHash = previousHash; this.transaction = transaction; this.timestamp = timestamp; }
}

В блоке у нас будет previousHash (хэш предыдущего блока в цепочке), transaction (объект класса Transaction) и timestamp (время создания блока). Теперь давайте создадим функцию для генерации хэша блока:

getHash() { const json = JSON.stringify(this); const hash = crypto.createHash("SHA256"); hash.update(json).end(); const hex = hash.digest("hex"); return hex;
}

Во-первых, мы конвертируем объект в формат JSON. Затем мы создаем хэш SHA256, который представляет собой метод хеширования, который нельзя расшифровать. Мы используем хеш для проверки блоков позже; он обеспечивает легитимность блока после проверки хэша.

Затем мы добавляем JSON в качестве данных, чтобы он был преобразован в хэш SHA256. Наконец, мы создаем hash.digest и возвращаем его. Теперь снова мы создаем функцию для преобразования объекта блока в JSON:

toString() { JSON.stringify(this);
}

Ваш полный класс Block теперь должен выглядеть так:

class Block { constructor(previousHash, transaction, timestamp = Date.now()) { this.previousHash = previousHash; this.transaction = transaction; this.timestamp = timestamp; } getHash() { const json = JSON.stringify(this); const hash = crypto.createHash("SHA256"); hash.update(json).end(); const hex = hash.digest("hex"); return hex; } toString() { return JSON.stringify(this); }
}

Теперь давайте создадим класс Chain.

Создание класса Chain

Теперь, когда у нас есть класс Block, мы можем заполнить блоки в Chain. Цепочка содержит каждый блок или каждую транзакцию, которая происходит в цепочке блоков. Как обсуждалось ранее, цепочка блоков содержит все блоки, связанные друг с другом, и нашему проекту нужен класс Chain, чтобы все блоки были собраны в одном месте.
Поскольку нам нужно инициализировать цепочку только один раз, а не несколько, мы сразу же инициализируем ее в самом классе:

class Chain { static instance = new Chain();
}

Давайте настроим конструктор так, чтобы у нас был готов первый блок в цепочке при каждом запуске программы. Также объявим массив, в котором будут размещены наши блоки.

Мы делаем так, чтобы устранить любые ошибки в проекте, потому что каждый блок зависит от предыдущего блока, и поэтому нам сначала нужно инициализировать фиктивный блок:

constructor() { this.chain = [new Block("", new Transaction(100, "temp", "temp"))];
}

Теперь нам нужна функция для получения последнего хэша цепочки, чтобы использовать информацию в новых блоках:

getPreviousBlockHash() { // sending the entire block itself return this.chain[this.chain.length - 1].getHash(); }

Затем давайте создадим функцию, которая фактически создаст и вставит блок в наш цепочный массив:

insertBlock(transaction, senderPublicKey, sig) { // create verifier const verify = crypto.createVerify("SHA256"); // add the transaction JSON verify.update(transaction.toString()); // Verify it with the sender's public key const isValid = verify.verify(senderPublicKey, sig); if (isValid) { const block = new Block(this.getPreviousBlockHash(), transaction); console.log("Block added", block.toString()); this.chain.push(block); }
}

Здесь мы сначала используем функцию createVerify из пакета crypto для проверки хэшей с открытыми ключами. Затем мы используем данные из JSON конкретной транзакции и, наконец, проверяем открытый ключ отправителя и подпись.

Это вернет логическое значение, которое мы можем использовать, чтобы проверить, была ли проверка успешной или неудачной. Если проверка прошла успешно, мы просто создаем новый блок и добавляем его в массив цепочки. Ваш класс Chain должен выглядеть так:

class Chain { static instance = new Chain(); // initializing our chain with no records constructor() { this.chain = [new Block("", new Transaction(100, "temp", "temp"))]; } getPreviousBlockHash() { // sending the entire block itself return this.chain[this.chain.length - 1].getHash(); } insertBlock(transaction, senderPublicKey, sig) { // create verifier const verify = crypto.createVerify("SHA256"); // add the transaction JSON verify.update(transaction.toString()); // Verify it with the sender's public key const isValid = verify.verify(senderPublicKey, sig); if (isValid) { const block = new Block(this.getPreviousBlockHash(), transaction); console.log("Block added", block.toString()); this.chain.push(block); } }
}

Создание класса Wallet

Давайте создадим кошельки, которые пользователи смогут использовать для отправки криптовалюты другим людям. У каждого криптокошелька есть пара ключей: открытый и закрытый ключи. Закрытые ключи используются для создания новых транзакций (например, для отправки криптовалюты), а открытый ключ используется для их проверки и получения криптовалют.

Давайте сначала настроим конструктор, чтобы мы могли сгенерировать пару ключей, как только кошелек будет инициализирован:

constructor() { const keys = crypto.generateKeyPairSync("rsa", { modulusLength: 2048, publicKeyEncoding: { type: "spki", format: "pem" }, privateKeyEncoding: { type: "pkcs8", format: "pem" }, }); this.privateKey = keys.privateKey; this.publicKey = keys.publicKey;
}

Мы используем формат PEM для ключей. Это хорошо известный формат, который может быть сохранен на компьютере пользователя. Алгоритм RSA позволяет создавать открытые и закрытые ключи. Теперь давайте создадим функцию, которая поможет нам отправлять криптовалюту на другие кошельки в сети:

send(amount, recieverPublicKey) { const transaction = new Transaction( amount, this.publicKey, recieverPublicKey ); const shaSign = crypto.createSign("SHA256"); // add the transaction json shaSign.update(transaction.toString()).end(); // sign the SHA with the private key const signature = shaSign.sign(this.privateKey); Chain.instance.insertBlock(transaction, this.publicKey, signature);
}

В приведенном выше коде мы берем amount и recieverPublicKey в качестве параметров и создаем новый объект класса Transaction, используя эту информацию. Затем мы создаем хэш транзакции и подписываем его закрытым ключом. Наконец, мы добавляем его в цепочку с помощью функции insertBlock.

Тестирование

Теперь, когда все готово, вы можете протестировать приложение, создав кошельки и транзакции:

const itachi = new Wallet();
const madara = new Wallet();
const orochimaru = new Wallet(); itachi.send(50, madara.publicKey);
madara.send(23, orochimaru.publicKey);
orochimaru.send(5, madara.publicKey); console.log(Chain.instance);

В приведенном выше коде я создал кошельки со случайными именами, а затем отправил деньги из одного кошелька в другой и, наконец, зарегистрировал цепочку, чтобы посмотреть, как она выглядит. Моя цепочка выглядела так (ваша может отличаться из-за разных хешей):

Chain { chain: [ Block { previousHash: '', transaction: [Transaction], timestamp: 1634561976555 }, Block { previousHash: 'c22300510c923a8ebf4d804f6edb4370731fcfd58f938d255852b4ea2744f20e', transaction: [Transaction], timestamp: 1634561976623 }, Block { previousHash: '1799ab15685e086cdb539e1851a759c713b3f71205664286cd4024c9f74d2a69', transaction: [Transaction], timestamp: 1634561976628 }, Block { previousHash: '1eb1f51c1b94a18f1c35e0cd81245ea6c69bac0100573cb76f3dac8026132597', transaction: [Transaction], timestamp: 1634561976629 } ]
}

Что дальше?

Это были только основы создания криптовалют с использованием JavaScript. Вы не должны использовать это в производстве, потому что криптовалюты включают в себя много разных вещей, таких как майнинг, и при этом задействованы большие меры безопасности.

Если вы где-то застряли, вы всегда можете посетить мой репозиторий GitHub, чтобы взглянуть на код. Если вы хотите поэкспериментировать еще больше, я бы порекомендовал включить в этот проект систему баланса кошелька и систему майнинга.

Автор: Atharva Deosthale

Источник: blog.logrocket.com

Редакция: Команда webformyself.

Читайте нас в Telegram, VK, Яндекс.Дзен