JavaScript to develop a simple blockchain takes only 200 lines of code. Through the JavaScript development process, you will understand what a blockchain is: a blockchain is a distributed database, the storage structure is an ever-growing list of ordered records.

However, in general, when we talk about blockchain, we also talk about using blockchain to solve problems, and it’s easy to confuse the two.

This is true of blockchain-based projects like the popular Bitcoin and Ethereum. The term “blockchain” is often associated with concepts like transactions, smart contracts, and cryptocurrencies.

This makes understanding blockchain unnecessarily complicated, especially if you want to understand the source code. To help you understand it, I’m going to use 200 lines of JAVASCRIPT to implement a super simple blockchain, which I’ve named NaiveChain. You can check out more technical details on Github.

Block structure of blockchain

The first logical step is to determine the block structure. To keep things as simple as possible, we select only the most necessary parts: index, timestamp, data, Hash, and previous Hash.

The hash value of the previous block must be found in this block to ensure the integrity of the chain. The JavaScript code is as follows:

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(); }}Copy the code

Blockchain block hashes

To preserve complete data, blocks must be hashed. Sha-256 encrypts the contents of the block, and recording this value should have nothing to do with “mining” since there is no proof of work to solve. The JavaScript code is as follows:

var calculateHash = (index, previousHash, timestamp, data) => {
    return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();
};
Copy the code

Generation of blockchain blocks

To generate a block, you must know the hash of the previous block and then create the rest of the required content (= index, hash, data and TIMESTAMP).

The data part of the block is provided by the end user. The JavaScript code is as follows:

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);
};
Copy the code

Storage of blockchain blocks

An in-memory Javascript array is used to store the blockchain. The first block of a blockchain is often called an “origin block” and is hard-coded. The JavaScript code is as follows:

var getGenesisBlock = () => {
    return new Block(0, "0", 1465154705, "my genesis block!!"."816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");
};
 
var blockchain = [getGenesisBlock()];
Copy the code

Verify block integrity

It must be possible at all times to verify the integrity of a block or the entire chain of blocks. This is especially important when we receive new blocks from other nodes and need to decide whether to accept or reject them. The JavaScript code is as follows:

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;
};
Copy the code

Choose the longest blockchain

There should be only one clear set of blocks in the chain at any one time. In the event of a collision (e.g., when both nodes produce blocks 72), the chain with the maximum number of blocks is selected. The JavaScript code is as follows:

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'); }};Copy the code

Communication with other nodes

The essence of a node is to share and synchronize the blockchain with other nodes, and the following rules keep the network in sync.

  • When a node generates a new block, it spreads the block across 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 current blocks, it either adds the block to its current chain or queries the block across the entire blockchain.

I did not use an automatic peer discovery tool. The location (URL) of peers must be added manually.

The node control

At some point the user must be able to control the node. This can be done by setting up an HTTP server. The JavaScript code is as follows:

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));
};
Copy the code

Users can interact with nodes in the following ways:

  • List all blocks
  • Create a new block with user-supplied content
  • List or add peers

Curl: Curl Curl: Curl Curl: Curl Curl: Curl Curl

#get all blocks from the node
curl http://localhost:3001/blocks
Copy the code

System architecture

It should be noted that the node actually represents two Web servers: one (HTTP server) that lets the user control the node, and the other (Websocket HTTP server).

conclusion

NaiveChain was created for demonstration and learning purposes, as it does not have a “mining” algorithm (PoS or PoW) that can’t be used on public networks, but it implements the basic features of blockchain operation.

More content can also be found on this Ethereum blog.

If you want to start learning taifang DApp development right away, you can visit the quick and effective online interactive tutorials provided by Weizhi:

  • Blockchain novice Ethereum DApp combat development entry
  • Blockchain advanced decentralized e-commerce platform combat development