200行JS代码实现超级简单的区块链,带你入门区块链

市面上有一个关于区块链的白皮书,有200多页,实在太长看不下去,本文通过JavaScript源码实现一个简单的区块链框架,带你入门区块链的相关知识。

区块链的基本概念非常简单:一个分布式数据库维持不断增长的有序记录列表。然而当我们谈论区块链时,我们也会谈论我们用区块链所要解决的问题,这二者通常很容易弄混淆。流行的基于区块链的项目如比特币和以太坊就是这种情况 。术语“区块链”通常与交易、智能合约或加密货币等概念紧密相关。

这使得理解区块链是一项必然要艰巨的任务。特别是源码级别的理解。在这里,我将介绍一个使用200行代码实现的超级简单的区块链——NaiveChain。

块结构

第一个逻辑步骤是确定块结构。为了让事情尽可能简单,我们只包含最必要的:索引index),时间戳timestamp),数据data),哈希hash)和上一个哈希previousHash)。

v2-75ad552ce74a27b6d6bfb39909a3fbf1_hd
class Block {
    constructorindex, previousHash, timestamp, data, hash) {
        this.index = index;
        this.previousHash = previousHash.toString);
        this.timestamp = timestamp;
        this.data = data;
        this.hash = hash.toString);
    }
}

块哈希

该块需要被哈希运算以保持数据的完整性。SHA-256被用来做哈希算法处理块的内容。需要注意的是这个哈希与“挖矿” 无关,因为没有解决工作量证明Proof Of Work )的问题。

var calculateHash = index, previousHash, timestamp, data) => {
    return CryptoJS.SHA256index + previousHash + timestamp + data).toString);
};

创建块

要创建一个块,我们必须知道上一个块的哈希,并创建剩余的所需内容(=索引,哈希,数据和时间戳)。块数据是由终端用户提供。

var generateNextBlock = blockData) => {
    var previousBlock = getLatestBlock);
    var nextIndex = previousBlock.index + 1;
    var nextTimestamp = new Date).getTime) / 1000;
    var nextHash = calculateHashnextIndex, previousBlock.hash, nextTimestamp, blockData);
    return new BlocknextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);
};

存储块

内存中的Javascript数组用于存储区块链。区块链的第一个区块也叫“创世纪块(译者著:genesis-block,区块链中的第一个块)”,它是直接写死的。

var getGenesisBlock = ) => {
    return new Block0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");
};

var blockchain = [getGenesisBlock)];

验证块的完整性

在任何时候,我们必须能够验证块或区块链的完整性。特别是当我们从其他节点接收到新块时,并且必须决定是否接受它们。

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 calculateHashForBlocknewBlock) !== newBlock.hash) {
        console.log'invalid hash: ' + calculateHashForBlocknewBlock) + ' ' + newBlock.hash);
        return false;
    }
    return true;
};

选择最长的链

任意时间,链中应始终只有一组块。如果发生冲突(例如下图中两个节点都生成id 为72的块),我们选择具有最长块数的链。

v2-0412f2ec088e8518a5933158ce7fffe3_hd
var replaceChain = newBlocks) => {
    if isValidChainnewBlocks) && newBlocks.length > blockchain.length) {
        console.log'Received blockchain is valid. Replacing current blockchain with received blockchain');
        blockchain = newBlocks;
        broadcastresponseLatestMsg));
    } else {
        console.log'Received blockchain invalid');
    }
};

与其他节点通信

一个节点的最重要的职能是与其他节点共享和同步区块链。以下规则用来保持网络同步。

  • 当一个节点产生一个新块时,它将它广播到网络
  • 当一个节点连接到一个新的节点时,它将查询最新的块
  • 当一个节点遇到一个索引大于当前已知块的块时,它会将该块添加到当前链中,或者查询完整的区块链。
v2-6ad134113dd1bff65f9c864b28646960_hd

我们暂未实现节点自动发现,必须手动添加对等点的位置(=URLs)。

控制节点

用户必须能够以某种方式控制节点。这是通过设置HTTP服务器完成的。

var initHttpServer = ) => {
    var app = express);
    app.usebodyParser.json));

    app.get'/blocks', req, res) => res.sendJSON.stringifyblockchain)));
    app.post'/mineBlock', req, res) => {
        var newBlock = generateNextBlockreq.body.data);
        addBlocknewBlock);
        broadcastresponseLatestMsg));
        console.log'block added: ' + JSON.stringifynewBlock));
        res.send);
    });
    app.get'/peers', req, res) => {
        res.sendsockets.maps => s._socket.remoteAddress + ':' + s._socket.remotePort));
    });
    app.post'/addPeer', req, res) => {
        connectToPeers[req.body.peer]);
        res.send);
    });
    app.listenhttp_port, ) => console.log'Listening http on port: ' + http_port));
};

如上所示,用户能够通过以下方式与节点交互:

  • 列出所有的块
  • 用用户给出的内容创建一个新块
  • 列出或添加节点

控制节点最直接的方法是使用Curl:

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

架构

值得注意的是,一个节点实际上暴露了两个Web服务器:一个用于控制节点(HTTP服务器),一个用于节点之间的点对点通信(Websocket HTTP服务器)。

v2-bf17ddebdbf27d73a12207febbceebcc_hd

结论

NaiveChain是为演示和学习目的而创建的。因为它不具有“挖矿”算法(PoS 或者 PoW),不能在公共网络中使用。尽管如此,它仍然实现了功能区块链的基本功能。

可以在这里查看源码以获取更多技术细节。

如果您想更多地了解区块链,我建议你看看Naivecoin: a tutorial for building a cryptocurrency系列教程。在这个教程里,我们将详细讨论更多概念,如采矿(PoW,工作量证明)、交易和钱包。

原文:https://zhuanlan.zhihu.com/p/34827027

 

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注