Blockchain technology has an impact on many of today’s game-changing innovations, from cryptocurrencies like Bitcoin to decentralized apps (DApps) in different fields. A blockchain is a shared ledger that keeps track of transactions across many computers so that the record can’t be changed after the fact. Each entry, or “block,” is connected to the one before it making a chain of blocks, which is why it’s called a “blockchain.” This setup makes sure data is open, secure, and can’t be altered, which is key for lots of uses
Javascript is a multifaceted and celebrated language especially suited for blockchain development. With its extensive ecosystem and strong community support, JavaScript simplifies blockchain development in several ways:
This article is designed for developers who are familiar with JavaScript and wish to delve into blockchain technology. It will guide you through setting up your development environment, understanding blockchain fundamentals, building a basic blockchain application, and exposing it via a simple API.
After you run the commands you should get the respective versions of the packages you installed if the setup is successful.
When you opt for JavaScript as your programming language the best partner to cater all the development needs is VsCode its robust features and versatile environment is best suitable.
JavaScript libraries are managed via npm. Initialize your project and install the required libraries with:
npm init -y npm install express body-parser crypto //express is the node framework //body-parser is the middle ware to parse the incoming requests //crypto function used for hashing |
A blockchain comprises of blocks, which contain:
const crypto = require(‘crypto’); class Block { constructor(index, timestamp, data, previousHash = ”) { this.index = index; this.timestamp = timestamp; this.data = data; this.previousHash = previousHash; this.hash = this.calculateHash(); } calculateHash() { return crypto.createHash(‘sha256’) .update(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)) .digest(‘hex’); } } |
Decentralization:
There is no central authority that holds all the necessary data or transaction validation rather it is all distributed across the network. As we know in blockchain, every node maintains a copy of the ledger which ensures there isn’t any discrepancy due to a single point of control.
Transparency:
All the nodes and participants can view the ledger ensuring transparency throughout the network. In Ethrerneum the transactions are visible on the blockchain explorer.
Immutability:
One needs to be very careful before executing any transaction because once it’s done it can’t be further altered. This property is quite helpful in preventing fraud and double-spending.
Consensus Mechanism:
Consensus mechanisms are a set of protocols that the nodes should follow in the network to agree on the state of the ledger. These mechanisms are used for the validation and authentication of transactions. These mechanisms ensure all nodes in the DLT agree on the state of the ledger.
Block structure in JavaScript:
const crypto = require(‘crypto’); class Block { constructor(index, timestamp, data, previousHash = ”) { this.index = index; this.timestamp = timestamp; this.data = data; this.previousHash = previousHash; this.hash = this.calculateHash(); this.nonce = 0; // For Proof of Work } calculateHash() { return crypto.createHash(‘sha256’) .update(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data) + this.nonce) .digest(‘hex’); } mineBlock(difficulty) { while (this.hash.substring(0, difficulty) !== Array(difficulty + 1).join(“0”)) { this.nonce++; this.hash = this.calculateHash(); } console.log(“Block mined: ” + this.hash); } } |
Creating and verifying transactions using JavaScript:
Transactions form the basic building blocks of data in a blockchain. They show a shift in value, carry out a contract, or make other changes to the blockchain’s condition. The system groups these transactions into blocks and puts them on the blockchain.
Details of the Transaction:
Code snippet for the transaction:
class Transaction { constructor(fromAddress, toAddress, amount) { this.fromAddress = fromAddress; this.toAddress = toAddress; this.amount = amount; this.timestamp = new Date().toISOString(); } calculateHash() { return crypto.createHash(‘sha256’) .update(this.fromAddress + this.toAddress + this.amount + this.timestamp) .digest(‘hex’); } signTransaction(signingKey) { if (signingKey.getPublic(‘hex’) !== this.fromAddress) { throw new Error(‘You cannot sign transactions for other wallets!’); } const hashTx = this.calculateHash(); const sig = signingKey.sign(hashTx, ‘base64’); this.signature = sig.toDER(‘hex’); } isValid() { if (this.fromAddress === null) return true; if (!this.signature || this.signature.length === 0) { throw new Error(‘No signature in this transaction’); } const publicKey = ec.keyFromPublic(this.fromAddress, ‘hex’); return publicKey.verify(this.calculateHash(), this.signature); } } |
Transaction verification confirms the legitimacy of a transaction by checking that the sender has properly signed it and that the sender has enough funds. This process usually involves validating the cryptographic signature and ensuring that the sender’s balance is equal to or greater than the transaction amount.
class Blockchain { constructor() { this.chain = [this.createGenesisBlock()]; this.pendingTransactions = []; this.miningReward = 100; } createGenesisBlock() { return new Block(Date.parse(‘2024-01-01’), [], ‘0’); } getLatestBlock() { return this.chain[this.chain.length – 1]; } minePendingTransactions(miningRewardAddress) { let block = new Block(Date.now(), this.pendingTransactions, this.getLatestBlock().hash); block.mineBlock(this.difficulty); console.log(‘Block successfully mined!’); this.chain.push(block); this.pendingTransactions = [ new Transaction(null, miningRewardAddress, this.miningReward) ]; } addTransaction(transaction) { if (!transaction.fromAddress || !transaction.toAddress) { throw new Error(‘Transaction must include from and to address’); } if (!transaction.isValid()) { throw new Error(‘Cannot add invalid transaction to chain’); } this.pendingTransactions.push(transaction); } getBalanceOfAddress(address) { let balance = 0; for (const block of this.chain) { for (const trans of block.data) { if (trans.fromAddress === address) { balance -= trans.amount; } if (trans.toAddress === address) { balance += trans.amount; } } } return balance; } isChainValid() { for (let i = 1; i < this.chain.length; i++) { const currentBlock = this.chain[i]; const previousBlock = this.chain[i – 1]; if (!currentBlock.hasValidTransactions()) { return false; } if (currentBlock.hash !== currentBlock.calculateHash()) { return false; } if (currentBlock.previousHash !== previousBlock.hash) { return false; } } return true; } } |
Proof of Work (PoW):
Technical Explanation: Proof of Work is also known as mining. In this consensus mechanism, the users have to solve cryptographic puzzles that reward them.It is a contest where the first one to solve gets to pass the new block. This algorithm uses hashing to secure the blockchain.
Developer Implementation: Tools for implementing PoW are provided by the Bitcoin Developer Environment like Bitcoin Core.
Proof of Stake (PoS):
Technical Explanation: Proof of Stake selects validators based on the number of coins they have and the stake as collateral. The selection process just doesn’t depend only upon the stake but also on factors such as the age of the coin and randomness. Validators having the lowest hash value and highest stake amount are chosen to add the new block
Developer Implementation: Tools and libraries for PoS are provided by Ethereum 2.0 SDK
Delegated Proof of Stake (DPoS):
Technical Explanation: Uses voting and delegates for validation of the transaction and creation of new blocks.
Developer Implementation: EOSIO SDK provides tools and libraries for DPoS.
In this you will learn about the blockchain structure, defining classes and block and block parameters, and how they are linked together.
Blockchain as the name represents is comprised of blocks and each block class bas attributes like:
Implement methods to calculate the hash of the block using JavaScript syntax:
Define a Blockchain class to manage the chain and implement methods to add new blocks:
class Blockchain { constructor() { this.chain = [this.createGenesisBlock()]; this.difficulty = 4; // Difficulty level for mining } // Method to create the genesis block createGenesisBlock() { return new Block(0, “01/01/2024”, “Genesis Block”, “0”); } // Method to retrieve the latest block in the chain getLatestBlock() { return this.chain[this.chain.length – 1]; } // Method to add a new block to the chain after mining it addBlock(newBlock) { newBlock.previousHash = this.getLatestBlock().hash; newBlock.mineBlock(this.difficulty); this.chain.push(newBlock); } // Method to validate the integrity of the blockchain isChainValid() { for (let i = 1; i < this.chain.length; i++) { const currentBlock = this.chain[i]; const previousBlock = this.chain[i – 1]; // Check if the current block’s hash is correct if (currentBlock.hash !== currentBlock.calculateHash()) { return false; } // Check if the current block’s previous hash matches the hash of the previous block if (currentBlock.previousHash !== previousBlock.hash) { return false; } } return true; } } |
Proof of Work, often referred to as mining, is a decentralized system in which network members, or miners, compete to solve cryptographic puzzles. The first miner to solve the puzzle adds the next block to the blockchain and receives a reward. This process uses hashing to secure the blockchain. The difficulty of PoW puzzles ensures the blockchain remains secure and controls the speed at which new blocks are added.
In the Block class, we can implement Proof of Work by adding a mineBlock method. This method adjusts the nonce until the block’s hash meets a specific difficulty target (e.g., the hash must start with a certain number of zeros).
Code Snippet:
class Block { constructor(index, timestamp, data, previousHash = ”) { this.index = index; this.timestamp = timestamp; this.data = data; this.previousHash = previousHash; this.hash = this.calculateHash(); this.nonce = 0; } // Calculate the hash of the block using SHA-256 calculateHash() { return crypto.createHash(‘sha256’) .update(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data) + this.nonce) .digest(‘hex’); } // Implementing Proof of Work mineBlock(difficulty) { while (this.hash.substring(0, difficulty) !== Array(difficulty + 1).join(“0”)) { this.nonce++; this.hash = this.calculateHash(); } console.log(`Block mined: ${this.hash}`); } } |
Update the Blockchain class to validate proof before adding new blocks.
class Blockchain { constructor() { this.chain = [this.createGenesisBlock()]; this.difficulty = 4; } // Create the genesis block createGenesisBlock() { return new Block(0, “01/01/2024”, “Genesis Block”, “0”); } // Get the latest block in the chain getLatestBlock() { return this.chain[this.chain.length – 1]; } // Add a new block to the chain addBlock(newBlock) { newBlock.previousHash = this.getLatestBlock().hash; newBlock.mineBlock(this.difficulty); // Implementing Proof of Work this.chain.push(newBlock); } // Check if the blockchain is valid isChainValid() { for (let i = 1; i < this.chain.length; i++) { const currentBlock = this.chain[i]; const previousBlock = this.chain[i – 1]; if (currentBlock.hash !== currentBlock.calculateHash()) { return false; } if (currentBlock.previousHash !== previousBlock.hash) { return false; } } return true; } } |
Just creating a blockchain is not enough one needs to make it usable in real life. For this purpose, we need to create an interface for interaction which will be a simple API.
Before you start with building the API setting up the environment with all the essential tools and frameworks is necessary.
Now that your environment is set up, let’s build the API. The API will allow users to interact with the blockchain, view the chain, and add new blocks.
Create the server with Express:
const express = require(‘express’); const bodyParser = require(‘body-parser’); const Blockchain = require(‘./blockchain’); // Import the Blockchain class const app = express(); app.use(bodyParser.json()); let demoBlockchain = new Blockchain(); // Initialize a new Blockchain instance |
Define API endpoints
app.get(‘/blocks’, (req, res) => { //endpoint to get the blockchain res.json(demoBlockchain.chain);}); //this is the endpoint to create a newblock app.post(‘/mine’, (req, res) => { const newBlock = new Block( demoBlockchain.chain.length, Date.now(), req.body.data, demoBlockchain.getLatestBlock().hash ); demoBlockchain.addBlock(newBlock); res.send(`Block successfully mined: ${newBlock.hash}`); }); |
Start the server
app.listen(3000, () => { console.log(‘Blockchain API running on port 3000’); }); node server.js |
This phase is critical to ensure that your blockchain is functioning correctly and that all features work as expected.
Postman is a widely used tool for testing APIs, allowing you to send HTTP requests and view the responses. It’s particularly useful for verifying the functionality of your blockchain API.
(Step1)node server.js Blockchain API running on port 3000 //http://localhost:3000/block (Step2)[ { “index”: 0, “timestamp”: 1636568887994, “data”: “Genesis Block”, “previousHash”: “0”, “hash”: “81f1a4ab4d484c64f1b4c524b1d8f2fef8f2bca7853d44682e12022fb2d803b9” } ] (Step3){ “data”: { “amount”: 100, “sender”: “John Doe”, “receiver”: “Jane Smith” } } (Step4){ “message”: “Block successfully mined”, “block”: { “index”: 1, “timestamp”: 1636578990123, “data”: { “amount”: 100, “sender”: “John Doe”, “receiver”: “Jane Smith” }, “previousHash”: “81f1a4ab4d484c64f1b4c524b1d8f2fef8f2bca7853d44682e12022fb2d803b9”, “hash”: “5a1cdd657c8d0d3c0f12c2bb2c9fdf32a7d2d4ad13fcb78170a8caa82ff4a9a2” } } (Step5)[ { “index”: 0, “timestamp”: 1636568887994, “data”: “Genesis Block”, “previousHash”: “0”, “hash”: “81f1a4ab4d484c64f1b4c524b1d8f2fef8f2bca7853d44682e12022fb2d803b9” }, { “index”: 1, “timestamp”: 1636578990123, “data”: { “amount”: 100, “sender”: “John Doe”, “receiver”: “Jane Smith” }, “previousHash”: “81f1a4ab4d484c64f1b4c524b1d8f2fef8f2bca7853d44682e12022fb2d803b9”, “hash”: “5a1cdd657c8d0d3c0f12c2bb2c9fdf32a7d2d4ad13fcb78170a8caa82ff4a9a2” } ] |
curl http://localhost:3000/blocks //View the blockchain [ { “index”: 0, “timestamp”: 1636568887994, “data”: “Genesis Block”, “previousHash”: “0”, “hash”: “81f1a4ab4d484c64f1b4c524b1d8f2fef8f2bca7853d44682e12022fb2d803b9” } ] //Mining a new blockcurl -X POST -H “Content-Type: application/json” -d ‘{“data”: {“amount”: 100, “sender”: “John Doe”, “receiver”: “Jane Smith”}}’ http://localhost:3000/mine //verify the blockcurl http://localhost:3000/blocks [ { “index”: 0, “timestamp”: 1636568887994, “data”: “Genesis Block”, “previousHash”: “0”, “hash”: “81f1a4ab4d484c64f1b4c524b1d8f2fef8f2bca7853d44682e12022fb2d803b9” }, { “index”: 1, “timestamp”: 1636578990123, “data”: { “amount”: 100, “sender”: “John Doe”, “receiver”: “Jane Smith” }, “previousHash”: “81f1a4ab4d484c64f1b4c524b1d8f2fef8f2bca7853d44682e12022fb2d803b9”, “hash”: “5a1cdd657c8d0d3c0f12c2bb2c9fdf32a7d2d4ad13fcb78170a8caa82ff4a9a2” } ] |
class Block { constructor(index, timestamp, data, previousHash = ”) { this.index = index; this.timestamp = timestamp; this.data = data; this.previousHash = previousHash; this.hash = this.calculateHash(); this.nonce = 0; } } |
calculateHash() { return crypto.createHash(‘sha256’) .update(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data) + this.nonce) .digest(‘hex’); } |
class Blockchain { constructor() { this.chain = [this.createGenesisBlock()]; } } |
getLatestBlock() { return this.chain[this.chain.length – 1]; } addBlock(newBlock) { newBlock.previousHash = this.getLatestBlock().hash; newBlock.hash = newBlock.calculateHash(); this.chain.push(newBlock);} |
mineBlock(difficulty) { while (this.hash.substring(0, difficulty) !== Array(difficulty + 1).join(“0”)) { this.nonce++; this.hash = this.calculateHash(); } } |
npm init -y npm install express –save //Setting up the project and the directory const express = require(‘express’); //Setting up the express server const bodyParser = require(‘body-parser’); const Blockchain = require(‘./blockchain’); // Assuming you have the Blockchain class from previous chapters const app = express(); app.use(bodyParser.json()); const demoBlockchain = new Blockchain(); app.get(‘/blocks’, (req, res) => { res.json(demoBlockchain.chain); }); app.post(‘/mine’, (req, res) => { //creating a new block const newBlock = new Block( demoBlockchain.chain.length, Date.now(), req.body.data, demoBlockchain.getLatestBlock().hash ); newBlock.mineBlock(2); // Assuming a difficulty of 2 for PoW demoBlockchain.addBlock(newBlock); res.send(`Block successfully mined: ${newBlock.hash}`); }); app.listen(3000, () => { //starting the server console.log(‘Blockchain API running on port 3000’); }); node server.js |
In postman send the request: GET request to http://localhost:3000/blocks. { “data”: { “amount”: 10, “sender”: “Alice”, “receiver”: “Bob” } } In curl:curl http://localhost:3000/blocks |
Lets summarize the above steps in short
Let’s go through the process step by step to bring your blockchain application to life:
Happy Coding!!
After failing to regain a bullish outlook on Friday during the Western financial markets, the…
Story Highlights The XRP Price LIVE: . The price could hit a high of $3.99…
The next two months could very well be the period of death for quite a…
Regulators worldwide are tightening their grip on crypto exchanges, and Thailand is no exception. The…
Story Highlights: XRP Price Today: It is presently changing hands at $2.14, with a drop…
Peter Brandt, a veteran market analyst, has identified a pattern in XRP’s price chart called a…