200行代码构建一个区块链

简介:

区块链的基本概念非常简单:一个存储不断增加的有序记录的分布式数据库。然而,当我们谈论区块链时,我们很容易将其与区块链要解决的问题混淆,比如误解为流行的,基于区块链的,像比特币和以太坊一样的项目。术语“区块链”通常与交易,智能合约或加密货币等概念紧密相关。

这必然使得理解区块链变成一项更艰巨的任务,特别是清楚地理解源代码。接下来我将介绍一个我用200行Javascript代码完成的超级简单的区块链:NaiveChain。

区块结构

第一个步骤是确定区块的结构。为了让事情尽可能简单,区块结构只包含最必要的部分:索引,时间戳,数据,散列值(hash)和前一个区块的散列值(hash)。

前一个区块的散列值(hash)必须能够在块中找到,这样才能保持链的完整性。
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算法生成这个值。应该指出,这个散列值与“ 挖掘 ” 无关,因为不需要去解决工作证明问题。

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数组在内存中存储区块链。区块链的第一个区块总是一个所谓的“创世纪区块”,内容是固定的。

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

选择最长的区块链

区块链中应时刻有且只有一组显式的区块。如果发生冲突(例如,两个节点都生成块号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');
    }
};

与其他节点通信

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

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

描述的模型中的一些典型的通信场景

不自动发现对等的节点,必须手动添加对等节点的位置(=网址)。

控制节点

用户必须能够以某种方式控制节点。可以通过设置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:

#从节点获取所有区块
curl http://localhost:3001/blocks

架构

应该注意的是,每个节点实际上公开了两个Web服务器:一个用于控制节点(HTTP服务器),一个用于节点之间的对等通信(Websocket HTTP服务器)

NaiveChain的主要组件

总结

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

您可以从Github存储库获取更多技术细节。

如果您想了解更多区块链的知识,我建议您查看Naivecoin:构建加密货币的教程。在这个教程中,我们将详细讨论如采矿(工作证明),交易和钱包这样的概念。



原文发布时间为:2018-03-15
本文作者:Mr.Crypto
本文来源:腾讯云 云+社区,如需转载请联系原作者。

目录
相关文章
|
3月前
|
供应链 监控 安全
构建未来:区块链技术在供应链管理中的应用
【8月更文挑战第30天】 在数字化浪潮的推动下,供应链管理正经历着前所未有的转型。本文深入探讨了区块链技术如何成为这一变革的核心动力。通过分析区块链的不可篡改性、透明度以及去中心化特性,揭示了其在提高供应链效率、确保商品真实性和加强各方信任方面的潜力。不同于常规摘要,本文还将提供具体的行业案例,以展现区块链技术在实际供应链管理中的应用场景与成效。
|
3月前
|
供应链 区块链 数据安全/隐私保护
构建未来的桥梁:区块链技术在现代金融中的应用
【8月更文挑战第16天】区块链技术,这一去中心化的数字账本技术,正逐渐渗透到金融领域的每一个角落。从提高交易透明度、降低操作成本到促进金融包容性,区块链正在重塑金融行业的未来。本文将探讨区块链技术如何在现代金融中发挥作用,以及它如何为金融服务的未来发展铺平道路。
|
4月前
|
算法 分布式数据库 区块链
Python构建区块链
【7月更文挑战第10天】本文探讨了如何使用Python构建基本的区块链应用。区块链作为去中心化的分布式数据库,由包含交易数据的区块组成,通过哈希链接形成不可篡改的链。文中通过Python代码展示了如何创建`Block`类和`Blockchain`类,实现了区块的创建、哈希计算和链的构建。此外,还讨论了如何扩展区块链,包括添加智能合约、实现共识算法如Proof of Work、优化网络层以及引入隐私保护和跨链技术。
65 6
|
5月前
|
供应链 算法 Java
使用Java构建区块链应用
使用Java构建区块链应用
|
5月前
|
供应链 安全 区块链
区块链模块化:构建灵活、可扩展的未来网络
**区块链模块化**拆分系统为独立模块,提升**可扩展性**和**安全性**,增强**灵活性**,适应不同场景需求,如跨链互操作、行业定制和公共服务。模块化设计促进系统**定制化**,支持快速迭代,是区块链技术发展和创新的关键趋势。
|
5月前
|
供应链 安全 物联网
区块链跨链互操性:打破孤岛,构建互联互通的未来
**区块链跨链互操性摘要** - 跨链互操性是不同区块链间通信、交换数据和价值的能力,旨在打破区块链孤岛,提高扩展性、促进创新和增强安全性。 - 实现方式包括侧链(灵活性高,需解决安全性和性能问题)、原子交换(去中心化,但有跨链通信挑战)和中继链(通用解决方案,面临安全和性能挑战)。 - 挑战在于兼容性、安全性和性能,未来趋势将是标准化、安全隐私提升及跨链应用多样化,促进生态协同发展。跨链桥和协议如DLIP、ZKP将扮演关键角色。
|
5月前
|
供应链 安全 物联网
区块链跨链互操性:打破孤岛,构建互联互通的未来
**区块链跨链互操性摘要** - 跨链互操性是不同区块链间通信、交换数据和价值的能力,打破区块链“孤岛”现象。 - 提升扩展性、促进创新、增强安全性是其主要益处,通过侧链、原子交换、中继链等方式实现。 - 面临兼容性、安全性和性能挑战,未来将趋向标准化、提升安全隐私,并拓展多样化应用,促进区块链生态协同发展。
|
5月前
|
供应链 安全 区块链
区块链模块化:构建灵活、可扩展的未来网络
**区块链模块化**通过拆分系统为独立模块,如执行、结算、共识和数据层,提升**可扩展性**、**安全性和灵活性**。模块化允许定制化解决方案,适用于跨链互操作、行业特定需求及公共服务,如电子投票和版权保护。此方法降低耦合,增强安全性,为开发者创造更多创新机会,驱动区块链技术的未来发展方向。
|
6月前
|
机器学习/深度学习 供应链 区块链
深度学习在图像识别中的应用与挑战构建未来:区块链技术在供应链管理中的应用
【5月更文挑战第31天】 随着人工智能技术的飞速发展,深度学习已成为推动计算机视觉领域进步的关键力量。特别是在图像识别任务中,深度神经网络凭借其强大的特征提取和学习能力,显著提升了识别的准确性和效率。然而,随着应用的深入,深度学习在图像识别中也面临着数据偏差、模型泛化能力不足、计算资源消耗巨大等挑战。本文将探讨深度学习在图像识别领域的应用现状,分析其面临的主要技术挑战,并对未来发展趋势进行展望。
|
6月前
|
物联网 区块链 Android开发
构建高效Android应用:Kotlin与Jetpack的实践之路未来技术的融合潮流:区块链、物联网与虚拟现实的交汇点
【5月更文挑战第30天】 在移动开发领域,效率和性能始终是开发者追求的核心。随着技术的不断进步,Kotlin语言以其简洁性和现代化特性成为Android开发的新宠。与此同时,Jetpack组件为应用开发提供了一套经过实践检验的库、工具和指南,旨在简化复杂任务并帮助提高应用质量。本文将深入探索如何通过Kotlin结合Jetpack组件来构建一个既高效又稳定的Android应用,并分享在此过程中的最佳实践和常见陷阱。