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

更新日期: 2018-04-25 阅读: 3.9k 标签: 区块链

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

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

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

块结构

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


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


块哈希

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

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


创建块

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

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


存储块

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

var getGenesisBlock = () => {
    return new Block(0, "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 (calculateHashForBlock(newBlock) !== newBlock.hash) {
        console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash);
        return false;
    }
    return true;
}


选择最长的链

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


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


与其他节点通信

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

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

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


控制节点

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

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

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

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

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

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


架构

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



结论

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

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

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

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


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/713

相关推荐

以太坊发展简史

在 以太坊在Serenity (ETH 2.0) 阶段来临之前经历的升级和硬分叉。通过本文将了解到升级或分叉发生的时间,加入那哪些特性。时至今日当我们鸟瞰区块链技术的发展,它仍旧算得上是一个新事物。

区块链开发中使用的最流行的编程语言

我们目前正处于一个新兴的区块链开发行业中。区块链技术处于初期阶段,然而这种颠覆性技术已经成功地风靡全球,并且最近经历了一场与众不同的繁荣。由于许多资金充足的项目现在急于建立区块链网络并在其上部署分散的应用程序

从概念到底层技术,一文看懂区块链架构设计(附知识图谱)

区块链作为一种架构设计的实现,与基础语言或平台等差别较大。区块链是加密货币背后的技术,是当下与VR虚拟现实等比肩的热门技术之一,本身不是新技术,类似Ajax,可以说它是一种技术架构,所以我们从架构设计的角度谈谈区块链的技术实现。

区块链开发的11种顶级编程语言

区块链是一种去中心化,安全且非常快速的技术,已经在商业世界引起轰动。随着大量的区块链项目正在开发和部署在互联网上,区块链开始走向世界。已经有一些公司试图在其他人的基础上发展。

区块链的六大层级结构

众所周知, 区块链 是 比特币 的底层技术,那么这个底层技术又是怎么分层级结构的呢?在前面我们介绍了区块链的四大核心技术是其独特的数据结构、分布式存储、密码学和共识机制。今天我们就来聊聊区块链结构的六个层级结构

DAG:区块链行业下一个引爆点?

DAG是Directed Acyclic Graph的缩写,是一种运用拓扑排序的直接图像数据结构。这种数据结构能够在数据压缩中找到最优解,因此在实际中被广泛地运用于数据处理等领域

用JavaScript写一个区块链

几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术。在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的

使用javascript实现小型区块链

区块链概念狭义:区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码方式保证的不可篡改和不可伪造的分布式账本。

什么是挖矿?

区块链中经常会听到挖矿这个名词,因为它和现实中的挖矿不一样,所以很多人对这个词很费解。为什么那么多人去挖矿呢?因为挖矿成功后会有奖励。为什么挖矿需要大量的矿机呢?因为有大量的哈希计算。这个计算的过程就被称为挖矿

初识区块链_用JS构建你自己的区块链

区块链太复杂,那我们就讲点简单的。用JS来构建你自己的区块链系统,寥寥几行代码就可以说明区块链的底层数据结构、POW挖矿思想和交易过程等。当然了,真实的场景远远远比这复杂。本文的目的仅限于让大家初步了解、初步认识区块链。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!