《Nodejs开发加密货币》之二十三:区块链

前言

亿书,是一款加密货币产品,用时髦的话说,更是一款实用的区块链产品。那么,区块链是什么?有那些特点?最近,以太坊硬分叉事件给了我们很多启示,能不能彻底杜绝区块链分叉行为?这一章,我们通过认真阅读和理解亿书相关的代码逻辑,来详细解释和说明这些问题,以便更加深入的了解和学习这项技术。

源码

blocks.js https://github.com/Ebookcoin/ebookcoin/blob/v0.1.3/modules/blocks.js

block.js https://github.com/Ebookcoin/ebookcoin/blob/logic/block.js

loader.js https://github.com/Ebookcoin/ebookcoin/blob/v0.1.3/modules/loader.js

类图

blocks-class.png

流程图

blocks-activity.png

解读

1.区块链是什么?

(1)基本概念

什么是区块链技术?为了感性认识这个问题,我们可以使用谷歌地球的例子做类比,ajax不是什么新技术,但组合在一起就成就了产品谷歌地球,与之类似,区块链也不是什么新技术,但与加密解密技术、P2P网络等组合在一起,就像ajax一样诞生了比特币。技术人员,特别是Web开发工程师,学习了解ajax技术最早是被谷歌地球酷炫的效果所吸引。而现在,历史再一次重演,很多人被比特币的疯狂发展所吸引,进而开始研究其背后的技术区块链。

使用学术点的文字来描述,区块链其实就是一种专用的数据存储技术,它使用特有的数据结构和数据形式来存储大量交易信息,每条记录从后向前有序链接起来,具备公开透明、无法篡改、方便追溯的特点。这里的交易不仅仅是一次购买支付行为,包括各类有价值、有所属的数字资产,所以更简单的说法是,区块链是去中心化的公共账本。区块链可以存储成文件形式,不过多数产品存储在一个数据库中,比如比特币使用Google的LevelDB数据库存储。

与加密货币相比,区块链这个名字抛开了代币的概念,更加形象化、技术化、去政治化,更适合作为一门技术去研究、去推广。

(2)从数据库设计角度理解区块链

用数据库的概念理解,区块链就是一张“自引用”的数据库表。每条记录代表一个区块,这条记录(区块)记录着它前面(时间上)一条记录的信息,可以直接查询到前一条记录,因此从任何一条记录开始都可以往前顺序追溯,直到第一条记录。普通自引用表结构,通常使用ID作为关联外键,加密货币使用的是经过加密处理的信息字段,具有签名认证作用,可实现自我验证,防止被篡改。

与区块链直接关联的另一张重要的表,就是交易表。加密货币包含大量的交易,我们之前分析过,交易可以是加密货币,也可以是债权、股权或版权等各类数字资产,这些交易保存在一张独立表里,并与区块链形成多对一的关联方式。如此以来,只要追溯到区块,就很容易查询到该区块包含的交易记录。这样,一个公开透明、无法篡改、方便追溯的账本就形成了。

上面是从数据库查询(读数据)的角度考虑的,如果从写入的角度思考,就更有意思了。写入是要根据需求不同进行不同的编码,我们前面的章节说过,加密货币的各种功能都可以通过扩展交易类型进行编码,如果把一些现实中的合同规则进行编码,要求系统在某个条件下自动执行(写入或更新)某交易,自然也是件简单轻松的事情,这就是“智能合约”的简单理解。

我们在第一部分提到过“智能合约”的概念,在这里再次提及,作为程序员能够更加直观的去理解编码上的可行性。“智能合约”也是目前加密货币社区讨论火热的概念,可以发挥你想象的翅膀,从加密货币扩展到现实世界的各种场景,比如:自动贩卖机、销售终端、大公司间的电子数据交换、银行间用于转移与清算的支付网络,以及音乐、电影和电子书等数字版权交易等。

(3)形象化理解区块链

人们通常把具有先后顺序的数据结构,使用栈来表示,比特币白皮书把这种结构进一步形象化,第一个区块作为栈底,然后其他区块按照时间顺序依次堆叠在上面,这样一来,区块与首区块之间的距离就表示“高度”,“顶端”就表示最新添加的区块。每个区块包含大量交易,就是包含在对应栈里的数据。我们可以把这样的结构想象成一个大大的橱柜,区块就是其中一个抽屉,每个抽屉里是满满的交易,就象下面这样:

stack-drawers.png

(4)区块链分叉

物理分叉。每一个区块都与它的前一区块(父区块)关联,而对它后面的区块(子区块)无限制,也就是说最顶端的区块,肯定知道它的父区块(已经写入区块链),但不知道子区块(或许还没有产生,也可能在传输的过程中)。我们知道,从物理层面,数据库、硬盘、网络的IO操作是最耗费时间的,在某一个时刻,多个最新区块同时找到父区块是很常见的现象,这就必然导致区块链分叉(从主链向多个方向发展)。这是在同一个软件版本(及其兼容版本)的情况下发生的,没有人为干预,不妨叫做物理分叉。

显然,物理分叉取决于物理环境,这与什么样的共识机制没有直接关系,不论是采取工作量证明机制(PoW)的比特币、还是采取股权证明机制(PoS)的点点币,亦或是这里采取授权股权证明机制(DPoS)的亿书币,都是如此。为了保持区块链的单一链条,解决分叉的最简单方式就是放任每个分叉继续增长,通常在下一刻就会出现差别,这时候软件选择最长的那个链条作为主链即可。在具体的设计开发过程中,这也是一个逻辑相对复杂的难点。

人为分叉。那么,如果存在人的干预,会怎么样呢?我们知道,世界上没有绝对完美的东西,人类开发设计的软件也不例外,漏洞是常有的,看看微软的windows系统时不时跳出来的漏洞修复提醒,就知道这类事情多么常见。而且,人类的需求始终在变化,软件要不断推出新功能来应对。所以,软件出现漏洞,或者添加新的功能,这类情况是再正常不过的事情。这时候,旧版本的软件对新版本软件产生的区块可能出现兼容性问题,甚至需要人为改变区块链的走向,这就导致新旧版本之间出现分叉,不妨叫做人为分叉。

很显然,人为分叉也是无法避免的事情。你可能认为很简单,有漏洞就修复吧,有新功能加上就得了,有什么好解释的。事实上,加密货币核心是交易,是价值转移的手段,规则的改变直接关系到所有持币人的利益。我们在第一部分说过,人是趋利的,要追求利益最大化,新功能能否保护用户的利益,还是代表了少部分利益集团的意志,应该如何约束和决策,这已经不单单是一个技术问题,更多的是社区政治问题,需要社区共同参与。历史证明,承载了较大资金盘的加密货币,在某一次分叉过程中,个别用户或矿工没有及时更新软件,就造成了直接经济损失。所以,每一个持币用户都非常关心任何一次分叉行为,都有可能站出来表达自己的意愿,甚至选择留在旧链上。

硬分叉和软分叉。它们都属于人为分叉,孰优孰劣也是当前社区分歧比较严重的问题。最初,社区区分这两个概念的简单方法就是,“硬分叉”是与旧版本的兼容度不高,但是获得了社区共识的规则明确的分叉行为,“软分叉”恰恰相反。发展到今天,只要是明确的“分叉”行为,大家都会寻求社区共识,所以二者的区别主要集中在软件兼容问题上了。这里的社区共识,是指包括软件开发者、矿工和使用者在内的整个软件社区,采取投票等方式,获得最大程度的一致性意见,通常是90%以上的社区成员同意就认为是达成了社区共识。比如最近以太坊为了应对The Dao遭受黑客攻击而实施的紧急硬分叉,就获得了社区87%的同意(接近90%,这里不讨论这次分叉行为的好坏)。

从技术角度讲,这里所谓的“硬”,主要体现在与旧版本的不兼容(或少量兼容)上,属于抛弃旧版本的行为,如果用户不升级软件,就永远留在旧链上,感觉上更加强硬得多。“软分叉”,最大程度的保持了对以前版本的兼容性,做得好的话,多个版本可以同时运行,类似于正常的版本迭代升级,用户可以自由选择是否升级。有人说“硬分叉”是很糟糕的事情,另一些人认为“软分叉”风险更大。事实证明,只要准备充分,操作得当,无论是“硬分叉”,还是“软分叉”,都不可怕,只不过“软分叉”在编码中需要考虑的情况更加复杂,对用户的影响较为隐蔽。

我个人不喜欢谈政治,但是作为交易媒介的新兴产物——加密货币,天生就是政治的附属品。这些货币的持续发展,往往是不同利益团体(包括开发者、矿工和用户)之间不断博弈的结果。最初是开发者主导,某个时期矿工的力量更加强大,后期用户的力量就不容忽视。也正是这些力量之间的制衡,才让加密货币相对持续稳健的发展,当这三种力量达到均衡的时候,就是这个加密货币相对成熟的时候。最近,以太坊硬分叉处理Dao遭受的黑客攻击事件,搅动了整个加密货币社区,不同利益者发出不同的声音,这是好事,充分说明加密货币仍处在初级阶段,还有很长的路要走。

2.区块链的特点

我们可以按照堆栈的方式理解数据结构,并采用自引用的关联方式设计数据库模型,但是做到这些,我个人认为并不代表就是区块链了,它还必须使用加解密技术,被置于去中心化的网络,由P2P网络节点共同维护,才能称得上区块链。当然,也有人持不同观点,他们认为一个中心化的应用,如果使用类似的数据结构,会更加安全(比不使用该结构的中心化系统),同时可以避免分叉,性能或许更高(比去中心化的系统),但事实上没有了P2P网络的支撑,这点改进算不上什么。我们之前分析过,P2P网络本身就是一条非常好的安全屏障,单点被攻击或被破解,对整个网络系统没有太大伤害,而任何中心化的系统仅仅相当于单节点,安全性大大降低。所以,为了那些许的性能改进,却要牺牲更好的安全性,有点得不偿失。

汇总以上信息,区块链应该具备这样几个特点:

  • 分布存储:区块链处于P2P网络之中,无论什么公链、私链,还是联盟链,都要采取分布式存储,使用一种机制保证区块链的同步和统一;
  • 公开透明:每个节点都有一个区块链副本,区块链本身没有加密,数据可以任意检索和查询,甚至可以修改(改了也没用);
  • 无法篡改:这是加密技术的巧妙应用,每一区块都会记录前一区块的信息,并实现验证,确保无法篡改。这里的无法篡改不是不能改,而是局部修改的数据,无法通过验证,要想通过验证,必须修改整个区块链,这在理论上可行,操作上不可行;
  • 方便追溯:区块链是公开的,从任一区块都可以向前追溯,直到第一个区块,并通过区块查到与之关联的全部交易;
  • 存在分叉:这是由P2P网络等物理环境,以及软件开发实践过程决定的,人们无法根本性杜绝。

也正是因为这样的特点,区块链的概念才逐渐火爆起来。实践证明,区块链技术能实现一切中心化应用的场景,可以解决(或更好的解决)很多中心化应用无法解决的问题,比如分布式财务管理、分布式存储、知识产权保护、电子商务,乃至物联网,特别是对于金融业而言,资金清算、审计等等,成本会大幅度降低。亿书,就是利用它公开透明、可追溯的特点,与数字出版结合起来,实现自媒体和版权保护,彻底解决当前数字出版版权保护不力的顽疾。

3.区块链开发应该解决的问题

明白区块链是什么和基本原理之后,就可以着手设计其基本功能了。从需求的角度说,设计中需要做到如下几点:

(1)加载区块链。确保本地区块链合法,未被篡改。

  • 保存创世区块
  • 加载本地区块
  • 验证本地区块

(2)处理新区块。加载后,该节点就可以处理网络中的交易了。

  • 创建新区块;
  • 收集整理交易,写入(关联)区块;
  • 把新产生的区块写入区块链;
  • 处理区块链分叉。

(3)同步区块链。确保本地区块链与网络中完整的区块链同步。

下面,我们从数据库设计出发,分别研读相关代码,认真讨论亿书区款链是如何运作的。

4.亿书区块链数据库设计

亿书使用SQLite数据库,与区块链相关的数据库结构如图:

blocks-database.png

blocks表是区块链,trs表是各种交易,forks_stat表代表分叉状态。从关联关系上看,blocks首先是一个自引用表,使用previousBlock关联;与trs是一对多的关系,一条记录关联多条交易;与forks_stat也是一对多的关系,意思是有分叉。

5.亿书区块链实现

这里按照上面提到的开发区块链要解决的问题,逐一对照,查看亿书技术实现。

(1)保存创世区块

创世区块是硬编码到客户端程序里的,会在客户端运行的时候,直接写入数据库。这样做的好处是保证每个客户端都有一个安全、可信的区块链的根。

// modules/blocks.js
// 78行
function Blocks(cb, scope) {
   
    library = sc
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值