如何创建你自己的区块链 Part1

2017 年 11 月 16 日 Python程序员

Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。

我现在依旧可以登录我的Coinbase账户,查看比特币钱包的历史,找到这条2012年的交易记录。那时一个比特币可以兑换6.5美元。如果我现在依然拥有那0.1个比特币,在我写这篇文章的时候它的价值已经超过了500美元。也许你们会好奇,我最后是在一个比特币价值2000美元时卖出的,所以我只得到了200美元——远少于现在500美元。哎,真应该继续持有的。

"谢谢你,Brain"

虽然知道比特币的存在,但是我一直没有深入的了解。我看到了 美元/比特币 汇率的涨跌,听到了人们讨论它有多大未来,也看到了杂志上批评它的文章。我从未对此发表过任何观点,只是跟随这些进行了解。

同样的,我对区块链技术本身了解的也很少。最近,我父亲多次提到,在看早间新闻时多次出现区块链这个词,但是他根本不知道这三个字代表着什么。

就在那个时刻,我觉得我应该更深入的学习区块链,而不只是了解上面提到的那些信息。我开始做了大量的"研究",我在网上尽可能多的寻找解释区块链的文章。这些文章有好有坏,有的太过浅显,有的又晦涩难懂。


在看了一些文章以后,我明白了一个道理,那就是 只阅读而不实践,是无法获得真正的知识的。所以我想,我应该通过尝试编写一个本地基础区块链来增加自己对它的理解。

在这里要提很重要的一点,我在文章里提到的基础区块链与专业的区块链是有差别的,这个链不会创建一种加密货币。实际上区块链并没有要求产生可交易货币,以及用其兑换实体货币。区块链是用来存储和验证信息的。虚拟货币只是用于激励更多人参与节点验证,不是必须要存在的。


我写这篇文章的原因有两个:

  1.阅读这篇文章的读者可以更了解区块链技术。

  2.我可以通过解释代码来学习更多,而不仅仅是写它。

在这篇文章中,我会展示1)存储区块链数据的方式,2)如何生成一个初始块,3)一个节点如何与本地区块链数据同步,4)怎样展示区块链(在未来与其它节点同步时会用到),5)通过挖矿创造一个有效的新区块。在这个系列的第一篇文章中,不会有其它节点出现。这里也没有钱包、细节和重要数据。这些会在后面的文章中提到。


长话短说


如果你不想太详细的了解并阅读代码,或者你只是在搜索区块链文章时碰巧看到了这篇文章,我会尝试写一个摘要来描述区块链是如何工作的。

从一个较高的层次上来看,区块链是一个人人都可以参与并进行存储,查看,确认的数据库,而且数据永远不会被删除。

从比较低的层次来说,只要这些特定的区块链允许,这些区块中的数据可以是任何东西。举个例子,在比特币区块链中存储的是账户间的比特币交易。以太坊区块链中存储了相同的以太币交易,但是其也包括运行代码的记录。

再往底层方面讲,在一个区块创建并链接到区块链之前,需要由区块链上的大多数人(通常称为节点)对其进行验证。“真正“的区块链是包含区块最多的那一条链,因为它被大多数节点验证为正确。这意味着如果一个节点尝试更改之前区块的数据,则较新的区块就不会被承认,而且节点也不会相信来自错误区块的数据。

如果你仍感到疑惑,不用担心,我也是花了很长时间才让自己搞明白。当然也要花更多时间写这篇文章,才能让一个对区块链一无所知的人有所了解。

第一步 - 类和文件


对我来说,第一步需要写一个类,来处理节点运行时的区块。我将这个类命名为Block。坦率的说,对于这个类我们并没有多少要做的。在这个_init_函数中,我们要相信所有需要的信息都由字典提供。如果自己写一个生成区块链,其实有些不明智,但是为了让文章中的例子更好理解,我还是写上完整代码。我还想写一个工具,将重要的区块信息放入字典中,这样当我在终端中打印区块信息时,可以将信息更好的展示。

我们可以使用很简单的代码,来创建第一个区块。

好的,本节最后一个问题是要将数据存储在文件系统中。存储后,我们关闭节点时就不会丢失本地区块的数据。

使用一种类似以太坊文件夹的方案,我将存储数据的文件夹命名为"chaindata"。现在每个区块都存储在以它的索引命名的文件当中。我们要确保文件名有足够多的前导零,使文件可以按照数字的大小顺序排列。

使用上面的代码,就可以创建第一个区块。


第二步 - 在本地同步区块链


当节点启动,在你进行挖矿,解释数据,或者为链发送/创建新数据之前,需要先同步节点。由于我们没有创建其他节点,我在这里只讨论从本地文件中读取区块。将来,从文件中读取也会是同步的一部分,但是同时也要与其他节点交流,以获取自己节点未运行时产生的其他区块。

现在这个函数还是简单易懂的。从文件夹中读取字符串并将其加载到数据结构中并不需要超级复杂的代码,所以上面这些代码即可完成任务。但是在后面的文章中,当我要实现不同节点之间的通信时,sync模块就要变得更加复杂了。


第三步 - 展示区块链


现在我们已经有了存储在内存中的区块链,下一步就是在将其在浏览器中展示。展示有两个用处,一是可以在浏览器中验证发生的改变,二是在将来可以使用浏览器对区块链进行查看及操作,比如转账及管理钱包。

在这我使用flask实现,因为它非常容易上手。

下面是显示区块链json的代码,我省略了导入包的过程以减少篇幅。

运行这个代码,访问localhost:3000/blockchain.json,你会看见当前的区块。


第四步 - “挖矿”,区块的产生


我们只有一个起源区块,如果想要存储和分发更多的数据,我们需要将其放入一个新区块中。此处要解决的问题就是,如何创建一个新的区块并与旧区块链接。

在比特币白皮书中,中本聪描述了一钟方法。请注意,"时间戳服务器"就是我们之前提到的"节点":

我们提出的解决方案从时间戳服务器开始。时间戳服务器的工作原理是将区块中Item的哈希值作为时间戳,然后广泛发布这个哈希值…时间戳用来证明在那个时刻数据是存在的,很显然,为了能够获取到哈希值。每个时间戳的哈希值当中包含之前的时间戳,每个附加的时间戳都包含更之前的时间戳,从而组成了一个链。

下面的图片描述了这个过程:

总的来说,这一步是为了将区块们链接在一起,我们使用一个哈希值来存储新区块的信息,包括区块的创建时间、之前区块的哈希值、以及该区块中的信息。我将把这组信息称为该区块的"header"。通过这种方法,我们可以通过遍历一个区块之前的所有哈希值并验证序列来检验该区块是否可信。

在这个例子中,我创建的头文件是将所有字符串的值添加到一个巨大的字符串中。

其中包括的数据有:

  1.索引,代表该区块的序号

  2.先前区块的哈希值

  3.数据,在这个例子中只是随机的字符串。对比特币来说,这被称为Merkle可信树的根,表示关于交易的信息。

  4.我们挖取区块时的时间戳

在混淆之前,将各种信息的字符串组合在一起并不需要创建header。这里的要求是每个人知道如何创建一个区块的header,并且在header中包含先前区块的哈希值。只有这样做,每个人才可确认新区块的哈希值是否是正确的,并确认两个区块之间的链接。

比特币的header是远比组合字符串复杂的。它使用了数据、时间的哈希值,并且解决了如何在计算机中存储字节的问题。但是在这个例子中,使用字符串已经足够了。

一旦我们有了header,我们需要通过计算哈希值来查看并验证哈希值的正确性。我在哈希值计算中将采用一些与比特币方法不同的东西,当然我依然使用sha256模块来运行header。

最后,使用上面的函数为新区块计算一个哈希值,将该值存储在新区块中,并将该区块加入chaindata的字典当中。

通过这种方式创建区块,拥有最快CPU的人可以创建被其他节点认可的、最长的链。我们需要减缓新区块的创建,并在移向下一个区块前相互确认。


第五步 - 验证工作(Proof-of-Work)


为了减缓速度,我将进行验证工作(Proof-of-Work),就像比特币做的那样。股权验证(Proof-of-Stake)是区块链用于达成共识的另一种方式,这种方式我会在后面实现。

实现这个的方式是调整每个区块的哈希值必须有确定属性的要求。比如比特币,在你可以移动到下一个区块之前,我会先确认当前的哈希值以确定数量的0开头。因此我会在header中多加入一项信息——Nonce(一个只被使用一次的任意或非重复的随机数值)。

现在调整挖矿模块来创建哈希值,但是如果区块的哈希值没有以足够的0开头,我们需要增加nonce值,然后创建一个新的header,计算一个新的哈希值,然后检查前方是否有足够的0。

完美~现在这个新区快包含了有效的nonce值,因此其他节点可以验证它的哈希值。现在我们可以生成、存储、以及将新区块进行分发。


总结


这篇文章就讲到这了!目前还有很多有关区块链的问题和特性没有提及。比如,其它节点如何参与进来?节点如何传输包含在区块中的数据?我们如何将信息存储在一个区块而不是一个大字符串中?还有不包含大型数据字符串的、形式更好的header吗?

在这个系列中会有更多部分来解决上面提出的问题。所以你想了解哪一部分,也欢迎给出你的建议。最后感谢我的妹妹Sara,她读了我的文章并提出了许多关于区块链的问题,所以我才能将文章写的浅显易懂。


英文原文:https://bigishdata.com/2017/10/17/write-your-own-blockchain-part-1-creating-storing-syncing-displaying-mining-and-proving-work/
译者:XTH
登录查看更多
0

相关内容

区块链(Blockchain)是由节点参与的分布式数据库系统,它的特点是不可更改,不可伪造,也可以将其理解为账簿系统(ledger)。它是比特币的一个重要概念,完整比特币区块链的副本,记录了其代币(token)的每一笔交易。通过这些信息,我们可以找到每一个地址,在历史上任何一点所拥有的价值。

知识荟萃

精品入门和进阶教程、论文和代码整理等

更多

查看相关VIP内容、论文、资讯等
【2020新书】实战R语言4,323页pdf
专知会员服务
98+阅读 · 2020年7月1日
【2020新书】从Excel中学习数据挖掘,223页pdf
专知会员服务
85+阅读 · 2020年6月28日
专知会员服务
142+阅读 · 2020年6月15日
【白皮书】“物联网+区块链”应用与发展白皮书-2019
专知会员服务
91+阅读 · 2019年11月13日
关于机器学习你要了解的 5 件事
机器学习算法与Python学习
7+阅读 · 2018年9月7日
零基础如何快速搭建一个推荐系统?
StuQ
5+阅读 · 2018年2月26日
一个小例子带你轻松Keras图像分类入门
云栖社区
4+阅读 · 2018年1月24日
【精华版】2017年区块链干货合集
FinTech前哨
4+阅读 · 2018年1月11日
【区块链】区块链是什么?20问:读懂区块链
产业智能官
8+阅读 · 2018年1月10日
如何用人工智能秒杀超级马里奥游戏
CSDN
4+阅读 · 2018年1月7日
用深度学习预测比特币价格
Python程序员
11+阅读 · 2017年12月23日
【动画连载】3分钟了解什么是区块链(中文动画)
Deep Learning for Deepfakes Creation and Detection
Arxiv
6+阅读 · 2019年9月25日
Learning Embedding Adaptation for Few-Shot Learning
Arxiv
16+阅读 · 2018年12月10日
Arxiv
4+阅读 · 2018年6月5日
Arxiv
11+阅读 · 2018年4月25日
Arxiv
7+阅读 · 2018年1月30日
VIP会员
相关VIP内容
相关资讯
关于机器学习你要了解的 5 件事
机器学习算法与Python学习
7+阅读 · 2018年9月7日
零基础如何快速搭建一个推荐系统?
StuQ
5+阅读 · 2018年2月26日
一个小例子带你轻松Keras图像分类入门
云栖社区
4+阅读 · 2018年1月24日
【精华版】2017年区块链干货合集
FinTech前哨
4+阅读 · 2018年1月11日
【区块链】区块链是什么?20问:读懂区块链
产业智能官
8+阅读 · 2018年1月10日
如何用人工智能秒杀超级马里奥游戏
CSDN
4+阅读 · 2018年1月7日
用深度学习预测比特币价格
Python程序员
11+阅读 · 2017年12月23日
【动画连载】3分钟了解什么是区块链(中文动画)
相关论文
Deep Learning for Deepfakes Creation and Detection
Arxiv
6+阅读 · 2019年9月25日
Learning Embedding Adaptation for Few-Shot Learning
Arxiv
16+阅读 · 2018年12月10日
Arxiv
4+阅读 · 2018年6月5日
Arxiv
11+阅读 · 2018年4月25日
Arxiv
7+阅读 · 2018年1月30日
Top
微信扫码咨询专知VIP会员