With 200 lines of code, you can easily implement a simple blockchain and 200 lines of code.
Lauri Hartikka
The basic concept of blockchain is simple: a distributed database stores an ever-increasing list, which contains many ordered records. However, when talking about blockchain, we often talk about the problems solved by using blockchain, which are easy to confuse. Blockchain-based projects like popular Bitcoin and ethereum are like this. The term "blockchain" is usually closely linked to concepts like transactions, smart contracts, and cryptocurrencies.
This makes it unnecessary to understand the blockchain, especially when you want to understand the source code. Next I will use the super simple blockchain implemented by line 1 JS to help you understand it. I will name this code NaiveChain.
Block Structure
The first logical step is to determine the block structure. To ensure that things are as simple as possible, we only select the most necessary parts: index (subscript), timestamp (timestamp), data (data), hash (hash value) and previous hash (pre-hash value ).
The hash value of the previous block must be found in this block to ensure the integrity of the entire chain.
class Block { constructor(index, previousHash, timestamp, data, hash) { this.index = index; this.previousHash = previousHash.toString(); this.timestamp = timestamp; this.data = data; this.hash = hash.toString(); }}
Block hash
To save the complete data, you must hash the block. The SHA-256 encrypts the contents of the block, recording this value should have nothing to do with "mining", because there is no need to solve the problem of proof of work here.
var calculateHash = (index, previousHash, timestamp, data) => { return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();};
Block generation
To generate a block, you must know the hash value of the previous block and then create other required content (= index, hash, data and timestamp ). The data part of the block is provided by the end user.
var generateNextBlock = (blockData) => { var previousBlock = getLatestBlock(); var nextIndex = previousBlock.index + 1; var nextTimestamp = new Date().getTime() / 1000; var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData); return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);};
Block Storage
The Javascript array in the memory is used to store the blockchain. The first block of a blockchain is hard-coded.
var getGenesisBlock = () => { return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");}; var blockchain = [getGenesisBlock()];
Verify block integrity
At any time, you must be able to check whether a block or a whole blockchain is complete. This is especially important when we receive new blocks from other nodes and decide to accept or reject them.
var isValidNewBlock = (newBlock, previousBlock) => { if (previousBlock.index + 1 !== newBlock.index) { console.log('invalid index'); return false; } else if (previousBlock.hash !== newBlock.previousHash) { console.log('invalid previoushash'); return false; } else if (calculateHashForBlock(newBlock) !== newBlock.hash) { console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash); return false; } return true;};
Select the longest chain
At any time, there should be only one set of clear blocks in the chain. In case of a conflict (for example, when both nodes generate block 72), a chain with the maximum number of blocks will be selected.
var replaceChain = (newBlocks) => { if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) { console.log('Received blockchain is valid. Replacing current blockchain with received blockchain'); blockchain = newBlocks; broadcast(responseLatestMsg()); } else { console.log('Received blockchain invalid'); }};
Communication with other nodes
The essence of a node is to share and synchronize the blockchain with other nodes. The following rules can ensure network synchronization.
When a node generates a new block, it will spread the block on the network.
When a node connects to a new peer, It queries the latest block.
When a node encounters a block whose index is greater than the index of all the blocks, it adds the block to its current chain or queries the block in the entire blockchain.
For some typical communication scenarios that occur when the node follows the preceding Protocol
I did not use a tool that automatically discovers peer. The peers location (URL) must be manually added.
Node Control
To some extent, you must be able to control nodes. This can be achieved by setting up an HTTP server.
var initHttpServer = () => { var app = express(); app.use(bodyParser.json()); app.get('/blocks', (req, res) => res.send(JSON.stringify(blockchain))); app.post('/mineBlock', (req, res) => { var newBlock = generateNextBlock(req.body.data); addBlock(newBlock); broadcast(responseLatestMsg()); console.log('block added: ' + JSON.stringify(newBlock)); res.send(); }); app.get('/peers', (req, res) => { res.send(sockets.map(s => s._socket.remoteAddress + ':' + s._socket.remotePort)); }); app.post('/addPeer', (req, res) => { connectToPeers([req.body.peer]); res.send(); }); app.listen(http_port, () => console.log('Listening http on port: ' + http_port));};
You can use the following method to interact with the node:
- List all blocks
- Create a new block with the content provided by the user
- List or add peers
The following Curl example is the most direct method for controlling nodes:
#get all blocks from the nodecurl http://localhost:3001/blocks
Architecture
It should be noted that the node actually shows two web servers: One (HTTP server) allows the user to control the node and the other (Websocket HTTP server ).
Main Components of NaiveChain
Summary
The purpose of creating NaiveChain is to demonstrate and learn because it does not have a "PoS of PoW" algorithm and cannot be used in public networks, however, it implements the basic features of blockchain operations.
You can view more technical details in the Github repository. Https://github.com/lhartikk/naivechain
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.