Create Your Own Cryptocurrency with JavaScript

Posted By : Mohd

Jun 28, 2023

Cryptocurrency is a decentralized form of digital currency that operates independently of a central bank or government. Cryptocurrency development relies on blockchain technology, which is a distributed ledger that records all transactions across multiple computers or nodes. In this blog post, we will simulate a blockchain with javascript code in which users can have wallets that contain public and private keys.

 

Cryptocurrency Development with JavaScript

 

We will simulate a blockchain using JavaScript code, where users can possess wallets containing public and private keys. Within this simulation, users have the ability to initiate transactions that are subsequently incorporated into blocks, eventually forming a complete blockchain structure.

 

For the implementation, we will have 4 classes - Transaction, Block, Wallet, and Chain.



Transaction Class

 

This class simulates the transaction on a blockchain

 

Constructor:

 

  • The constructor method is called when a new instance of the Transaction class is created.
  • It takes three parameters: amount, senderAddress, and receiverAddress.
  • These parameters represent the amount of the transaction and the addresses of the sender and receiver, respectively.
  • Inside the constructor, the values are assigned to the corresponding properties of the transaction object.

 

toString() method:

 

  • This method converts the transaction object to a string representation.
  • It returns a JSON string representation of the transaction object using JSON.stringify(this).
  • The ‘this’ keyword refers to the current transaction object.

 

Suggested Post | MPC Wallet Development | Enhancing Crypto Asset Security

 

Block Class

 

This class simulates the blocks on the blockchain.

 

Constructor:

 

  • The constructor method is called when a new instance of the Block class is created.
  • It takes three parameters: previousHash, transaction, and timestamp.
  • previousHash represents the hash of the previous block in the chain.
  • transaction is the transaction associated with the current block.
  • timestamp is an optional parameter representing the timestamp of when the block was created. If not provided, the current timestamp (obtained using Date.now()) is used.
  • Inside the constructor, the values are assigned to the corresponding properties of the block object.

 

getHash() method:

 

  • This method calculates and returns the hash of the block.
  • It converts the block object to a JSON string representation using JSON.stringify(this).
  • It then uses the SHA-256 algorithm from the crypto module to compute the hash of the JSON string.
  • The resulting hash is returned as a hexadecimal string.

 

toString() method:

 

  • This method converts the block object to a string representation.
  • It returns a JSON string representation of the block object using JSON.stringify(this).
  • The ‘this’ keyword refers to the current block object.

 

Also, Visit | AI Crypto Trading Bots | Reshaping Crypto Trading

 

Wallet Class

 

This class simulates the wallet on the blockchain.

 

Constructor:

 

  • The constructor method is called when a new instance of the Wallet class is created.
  • Inside the constructor, a key pair is generated using the crypto.generateKeyPairSync() function from the crypto module.
  • The generateKeyPairSync() function generates a public-private key pair using the RSA encryption algorithm.
  • The key pair is then stored in the privateKey and publicKey properties of the wallet object.

 

send(amount, receiverAddress) method:

 

  • This method facilitates a transaction by creating a new Transaction object, signing it with the sender's private key, and inserting a new block into the blockchain.
  • It takes two parameters: amount (the amount to be sent in the transaction) and receiverAddress (the address of the recipient).
  • Inside the method, a new Transaction object is created using the provided amount, the wallet's publicKey as the sender's address, and the receiverAddress as the recipient's address.
  • The crypto.createSign() function is used to create a sign object with the SHA-256 hashing algorithm.
  • The update() method of the sign object is called with the transaction converted to a string using transaction.toString().
  • The sign() method is then called on the sign object, passing the wallet's privateKey to sign the transaction.
  • The resulting signature is passed along with the transaction and the wallet's publicKey to the insertBlock() method of the Chain class, adding a new block to the blockchain.

 

Chain Class

 

This class simulates the blockchain itself.

 

Constructor:

 

  • The constructor method is called when a new instance of the Chain class is created.
  • Inside the constructor, the initial state of the blockchain is set by creating a genesis block.
  • The genesis block is created using an empty string as the previous hash and a default transaction with zero amount and arbitrary sender and receiver addresses.
  • The genesis block is then stored as the first block in the chain array.

 

getPreviousBlockHash() method:

 

  • This method returns the hash of the previous block in the chain.
  • It retrieves the last block in the chain array using this.chain[this.chain.length - 1].
  • The getHash() method of the block object is called to obtain its hash.

 

insertBlock(transaction, senderAddress, sig) method:

 

  • This method inserts a new block into the blockchain after verifying the integrity and authenticity of the provided transaction.
  • It takes three parameters: transaction (the transaction to be included in the block), senderAddress (the address of the transaction sender), and sig (the signature of the transaction signed by the sender).
  • Inside the method, a crypto.createVerify() object is created with the SHA-256 hashing algorithm to perform the verification.
  • The update() method of the verify object is called with the string representation of the transaction obtained using transaction.toString().
  • The verify() method is then called on the verify object, passing the senderAddress and the sig to verify the signature.
  • If the signature is valid, a new block is created using the getPreviousBlockHash() method to retrieve the previous block's hash.
  • The new block is added to the chain array using this.chain.push(block).

 

getBalance(address) method:

 

  • This method calculates and returns the balance of a user based on their address.
  • It takes one parameter: address (the address of the user).
  • Inside the method, a variable named balance is initialized to zero.
  • The method iterates over each block in the chain array using forEach().
  • For each block, it checks if the senderAddress of the block's transaction matches the given address. If true, it subtracts the transaction amount from the balance.
  • It also checks if the receiverAddress of the block's transaction matches the given address. If true, it adds the transaction amount to the balance.
  • Finally, the calculated balance is returned.

 

Check It Out | Hiring Smart Contract Developers Made Easy"‹"‹"‹"‹"‹"‹"‹

"‹"‹"‹"‹"‹"‹"‹

const crypto = require('crypto');

 

// Transaction class to demostrate transactions on blockchain

class Transaction {

 // A transaction will have amount, sender address, reciever address

 constructor(amount, senderAddress, recieverAddress) {

   this.amount = amount;

   this.senderAddress = senderAddress;

   this.recieverAddress = recieverAddress;

 }

 

 // Convert the transaction details to string

 toString() {

   return JSON.stringify(this);

 }

}

 

// Block class to demonstrate blocks in blockchain

class Block {

 // A block consists of hash of previous block, transactions and time

 constructor(previousHash, transaction, timestamp = Date.now()) {

   this.previousHash = previousHash;

   this.transaction = transaction;

   this.timestamp = timestamp;

 }

 

 // Function to get the hash of the block

 getHash() {

   const json = JSON.stringify(this);

   const hash = crypto.createHash('SHA256');

   hash.update(json).end();

   const hex = hash.digest('hex');

   return hex;

 }

 

 // Convert the block details to string

 toString() {

   return JSON.stringify(this);

 }

}

 

class Wallet {

 constructor() {

   // Create public and private keys at the time of instantiation

   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;

 }

 

 // Function to send the transaction

 send(amount, recieverAddress) {

   const transaction = new Transaction(

     amount,

     this.publicKey,

     recieverAddress

   );

   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);

 }

}

 

// Chain class to demonstrate the blockchain itself

class Chain {

 // Only instance of the chain class

 static instance = new Chain();

 

 // initializing our chain with no records

 constructor() {

   this.chain = [new Block('', new Transaction(0, 'abc', 'xyz'))];

 }

 

 // Returns the hash of the previous block

 getPreviousBlockHash() {

   // sending the entire block itself

   return this.chain[this.chain.length - 1].getHash();

 }

 

 // Add new block in the chain

 insertBlock(transaction, senderAddress, 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(senderAddress, sig);

 

   if (isValid) {

     const block = new Block(this.getPreviousBlockHash(), transaction);

     console.log('Block added: ', block.toString());

     this.chain.push(block);

   }

 }

 

 // Function to get the balance of a user

 getBalance(address) {

   let balance = 0;

   this.chain.forEach((block) => {

     if (block.transaction.senderAddress === address) {

       balance -= block.transaction.amount;

     }

 

     if (block.transaction.recieverAddress === address) {

       balance += block.transaction.amount;

     }

   });

   return balance;

 }

}

 

const satoshi = new Wallet();

const vitalik = new Wallet();

const sid = new Wallet();

 

satoshi.send(50, vitalik.publicKey);

vitalik.send(23, sid.publicKey);

sid.send(5, vitalik.publicKey);

 

const vitalikBal = Chain.instance.getBalance(vitalik.publicKey);

const sidBal = Chain.instance.getBalance(sid.publicKey);

 

console.log(Chain.instance);

console.log('Vitalik has: ', vitalikBal);

console.log('Sid has: ', sidBal);


 

Leave a

Comment

Name is required

Invalid Name

Comment is required

Recaptcha is required.

blog-detail

November 21, 2024 at 11:20 am

Your comment is awaiting moderation.

By using this site, you allow our use of cookies. For more information on the cookies we use and how to delete or block them, please read our cookie notice.

Chat with Us
Telegram Button
Youtube Button

Contact Us

Oodles | Blockchain Development Company

Name is required

Please enter a valid Name

Please enter a valid Phone Number

Please remove URL from text