30分钟自己写一条区块链(一)

阅读时间:10分钟闲扯一点

在币圈风起云涌,币价高歌猛进的去年,我们在背后看到了有很多优秀的区块链产品出现,也看到了有很多以圈钱为目的的“空气币”,很多人对于区块链的兴趣也越来越浓,那么加密货币背后的区块链到底有多少技术含量?甚至我们能否,如何从无到有实现一条区块链? 答案当然是肯定的,我们可以造一条链。今天,我们简单的来做一下这件事情。

(图为第一个诞生的以太猫,价值250ETH,截止发稿约值28万美元)

加密货币是什么?

加密货币,在绝大多数的实现里,只是其区块链里对应的账号里的余额而已。每次交易,在绝大多数区块链节点证明了交易合法的情况下,余额从一个账户转移到另一个账户并进行全网更新。同时,付出了计算能力的节点,能够获得交易产生的费用,就像银行转账的手续费。

区块链是什么?

一般来说,区块链(BlockChain)是由一个一个的叫做区块的账本组成,所有账本在每一个维护区块链网络的节点上都有完整的拷贝,每一个区块通过对上一个区块的内容进行哈希(Hash),而链在一起的分布式系统。每一个区块都能包含很多的交易,文件,或者任意数据。这些数据在新的区块被发现后,会被整体的进行哈希,成为一段很短的哈希码,存储在新的区块里。 如果你不确定什么是哈希的话,可以先移步原味区块的另一篇文章:什么是哈希?5分钟让你明白

(比特币的区块链示意图,每一个区块存有前一个区块所有内容的哈希)

区块链的不可更改性正是通过这样的链式哈希而实现的,试想,如果我想改变一个区块里的内容,那么必然会改变它的哈希值,也就意味着之后的所有区块里的哈希值都必然改变,那维护网络的节点当然是不会同意了,除非我的算力能够大于全网50%的算力(在有些情况下,进行attack的算力要求会更低)。

如何从技术上实现一条区块链?

首先,这里假定读者有基本的编程能力,虽然本文用了Javascript来写,但掌握任意一门编程语言的读者阅读起来应该不会有任何难度。

开发准备

我们首先需要安装最新版的Node.js, 可以通过NVM来进行安装。

第一步,搭建区块链模型

我们首先来搭一个能够新建区块,创建交易的区块链的模型。

这里要解释一下区块(block)和交易(transaction)各自长什么样,虽然不同区块链的区块模型有很大差异,但最基本的一些元素都是相通的。一个最基本的区块大概长下面这样:

可以看到,一个区块包含了它被挖出来的时间戳(timestamp),它在区块链里的位置(id),它的证明(proof, 更多的会在之后讲到),前一个区块的整体哈希值(previousBlockHash),包含的交易(transactions)。 作为一个最基本的交易模型,每一个交易只包含了发送者的地址(sender),接受者的地址(receiver),以及这次交易的价值(value)。

第二步,实现基本功能工具函数

这里我们首先实现一个工具函数Hash(block), 它会帮助我们将一个区块进行哈希。这个函数会在我们进行挖矿(发掘新区块)的时候用到。

这个函数将一个区块,也就是一个Javascript object,哈希成一段字符串。我们使用了crypto这个工具,在最新版的Node.js里面已经是内置了,所以我们并不需要安装它。

创建一个新交易

下一步,我们实现创建新交易的方法。

非常直观,我们只是创建了一个object,加入到区块链里并返回而已。

创建一个新区块

我们现在来实现创建一个区块的代码。当我们的区块链连一个区块也没有的时候,我们需要建立第一个区块(genesis block),这一点我们在constructor里面实现。

在创建一个新区块的时候,我们用了当前时间的时间戳,以现在区块链的长度作为id,初始的proof设置为0(proof会在下一步详细讲到),并将上一个区块整体进行哈希并赋值给previousBlockHash。在创建genesis 区块的时候,我们将previousBlockHash设置为1。 为了便于理解,我们建立新区块的时候没有附上任何交易,实际的情况是矿工可以自主选择包含哪些交易,并需要对这些交易进行处理得到一个默克尔树。

理解挖矿:找到有效的Proof

读者朋友们应该都听说过工作量证明(Proof of Work),POW是区块链中用来创造区块的核心算法或者机制。POW本身的目的是为了找到一个数字来解决一个数学问题,而找到这个数字的难度是越来越高的,但一旦找到之后,要证明它解决了这个数学问题又是非常容易的,任何人都能很快做到。 当然除了Proof of Work之外,我们还有Proof of Space, Proof of Stake,在代码里我们就用proof来代表找到的这个数字。 那么这个数学问题到底是什么呢?我们用一个例子来回答。

给定一个数字A,我们想找到数字B,使得Hash(A*B)的结果C的最后1位等于0。也就是说,C可以是Hash(A*B)=2ba83...6d0,因为它的最后一位是0。如果我们用Javascript来找到这个B的话,可以这样做:

我们试着在终端里跑一下这段代码,可以看到我们找到了一个数24可以满足这样的条件。

可以想象,如果我们要求最后的哈希值的最后2位都为零,甚至3位,4位,那么找到B的难度就应该更高,这也就是POW调整挖矿难度的方法。

实现挖矿

知道了如何挖矿之后,我们将上面的代码融合到我们的区块链模型里。

因为我们一开始就定义了如何哈希一个区块,这里我们就可以复用啦。 到此为止,我们已经基本实现了区块链的创建区块,创建交易等功能。整体的代码贴在了下方。下一次,我们将把我们写好的区块链API化并部署到多个节点上去,敬请期待啦。

识别下方二维码,关注【原味区块】

持续关注区块链本身

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180119G01L2800?refer=cp_1026

相关快讯

扫码关注云+社区