前言
对于区块链的各种解释非常多,很多都是从大众的角度去解释什么是区块链,但是区块链本身是一个相对偏技术的比较抽象的一个概念,通过通俗语言解释出来的区块链难免都会有点变味,这也导致了很多刚入门的朋友在听了这些解释后反而更加迷惑了一脸的黑人问号。笔者第一次听到最多的对于区块链的解释为区块链就是比特币的底层技术实现
,听了之后心里一万只神兽奔腾而过,这说了和没说一样,也有一些通过一些简单的卡通图进行解释,号称XX图解区块链,这些我扫过几篇,发现大部分解释的也不是很明确,但是对于做技术的同学来说还是不清楚,区块链底层到底是怎么样的。所以笔者也计划赶潮流写几篇区块链的文章,目前计划是先写3篇,《从程序员视角解读区块链》、《目前的区块链适用于哪些业务场景》、《动手写框架-MkBlockChain》,这三篇都是从程序员的角度去解析区块链,先从各种概念上用偏技术的语言解读区块链,学任何一个技术都要先了解到这个技术能用在哪些地方,接下来会再写一篇区块链技术可以用于哪些业务场景的文章,最后会通过写一个开源的区块链框架来让程序员能够从实现上了解区块链到底是怎么运行的,通过这三部曲程序员基本能够跨国区块链的第一个门槛了。
区块链的各种定义
区块链说白了不是一个系统也不是一个产品,而是一套协议,一个权力分散并且完全自治的生态,更是一种全新的经济体系和写作方式。
从程序员角度看区块链的技术其实都是目前非常成熟的技术,简单说就是分布式数据库(去中心化、去中央集权、数据共享)+共识算法 + 加密算法
。
要认识区块链我们先从白皮书中的各种定义入手,否则后面说到区块链架构的时候也很难理解。
区块结构
上图为区块链的基础结构,区块之间是常见的链表结构,每个节点代表一个区块,整个区块中包含两大部分组成,区块头和区块体,下面我们拆解下区块数据结构看下区块组成。
Block:{
区块头:{
版本:定义协议版本,
父区块hash:指向父区块的hash值,
Merkle根:该区块所有交易的Merkle根哈希值,
时间戳:区块产生的时间,
Nonce:工作量证明算法计算的数值,
难度系数:计算区块的难度系数
},
区块大小:用字节单位表示整个区块大小,
区块hash:当前区块sha256后的hash值,
交易:{
发送hash地址:发送方的hash地址,
接收hash地址:接收方的hash地址,
交易量:交易转移的交易量
}
}
从上面这个区块数据结构可以很容易的了解到区块头和区块体的关系并能了解到内部有哪些内容组成。
交易UTXO
UTXO是Unspent Transaction Output的缩写,指未花费的交易输出,此模型表达了一种转移的概念,即任何产生的新币,在以后的生命周期中,只有转移,没有消亡,转移实质上是由加密算法的签名与验证控制的。它是区块链中数字货币交易过程中的基本单位,除创世区块、挖矿奖励交易外,其他所有交易都存在一个输入资金地址一个输出资金地址,一笔交易的输入资金地址必须是另一比交易的未使用输出资金地址,同时这笔输入资金地址需要上一笔输出资金地址所对应的私钥进行签名。
那么如何去验证交易的合法性?在每个区块链的网络中所有的UTXO会被保存在每个上链节点中,只有满足了数字签名条件的交易才是合法的,才能上链,如果交易被篡改或者签名私钥不正确,那么其他节点在验证交易的时候会认为是失败的,无法验证通过后区块上链。
工作量证明
我们常说的挖矿其实就是一个生产工作量证明的过程,节点通过工作量证明这个共识机制,在区块链上争夺区块的记账权,因为第一个记账的节点是能够获得系统分配的记账奖励的,在币圈奖励也就是比特币或其他代币。
常用的工作量证明算法就是穷举算法,目前常用的穷举算法是:
sha256(10分钟内发生的全部交易+父区块hash+随机数)
对比难度系数,如果符合难度规则则全网广播,如果不符合难度规则,则换其他随机数继续运算,以此循环。(难度系数一般是计算出的hash前N位是0,每增加一位难度指数级上升,通过控制难度系统可以达到控制区块生成速度的功能)
分叉
当共识机制在执行过程中,可能会出现不同节点的两个矿工同时“挖出”两个新区块加以链接的情况,这时主链上就会出现“分叉”。系统并不会马上确认哪个区块不 合理,而是约定后续矿工总是选择累计工作量证明最大的区块链。因此,当主链分叉以后,后续区块的矿工将通过计算和比较,将其区块链接到当前累计工作量证明最大化的 备选链上,形成更长的新主链,并自动抛弃分叉处的短链,从而解决分叉问题。所以从这里我们也可以发现由于区块链是个分布式系统,需要保证最终的数据一致性,所以在过程中会产生分叉,虽然分叉最终会根据规则约定主链最终取长链的逻辑来解决所有节点最终一致性,但是如果并发很高,就有可能导致主链上经常产生分叉,使得处理分叉的成本很高,每个节点的大部分时间都是在处理分叉做分链取舍和分链复制的工作。
分叉按照对老链的兼容性分为软分叉和硬分叉:
软分叉:在区块链或去中心化网络中向前兼容的分叉。向前兼容意味着,当新共识规则 发布后,在去中心化架构中节点不一定要升级到新的共识规则,因为软分叉的新规则仍 旧符合老的规则,所以未升级的节点仍旧能接受新的规则。
硬分叉:在区块链或去中心化网络中不向前兼容的分叉,硬分叉对加密货币使用的技术 进行永久更改,这种变化使得所有的新数据块与原来的块不同,旧版本不会接受新版本 创建的区块,要实现硬分叉所有用户都需要切换到新版本协议上。如果新的硬分叉失败 ,所有的用户将回到原始数据块。以太坊的硬分叉是比较知名的经典硬分叉事件分为了以太坊(ETH)和以太经典(ETC)。
注:
The DAO计划基于以太坊智能合约建立一个众筹平台,于2016年5月正式发布,截止当年6月,募集资金超过1.6亿美元。之后,The DAO被黑客利用智能合约的漏洞,转移了市值五千万美元的以太币。为了挽回投资者资产,以太坊社区投票表决决定将更改以太坊代码,希望索回资金。为此,以太坊在第1920000区块进行硬分叉,回滚所有以太币(包括被黑客占有的)。
但是,有一部分人认为以太坊这种作法违背了区块链的去中心化和不可篡改精神,坚持在原链上挖矿,从而形成两条链,一条为不承认回滚交易的链-以太经典(ETC),一条为承认回滚交易的链即以太坊(ETH),各自代表不同的社区共识以及价值观。分叉时持有以太币的人在分叉后会同时持有ETH和ETC。
如何防篡改
1)hash
hash的特点是单向性和一致性,上面我们看了区块的数据结构中有个字段是区块hash值,他代表了这个区块在整个链条上的唯一性。因为hash的单向性保证了,区块的hash值在一定时间内没办法进行逆向,除非是对所有的字符串进行全hash,然后进行hash值碰撞。
2)数字签名
区块链中使用的数字签名算法是非对称算法,常用的RSA、ECC都可以做为区块链的数字签名算法,通过非对称算法私钥做过签名得出的区块地址是很难被仿冒的,接收方通过对地址进行公钥验证和hash比对就能够知道交易是否合法有没有篡改。
3)分布式结构
通过分布式结构能够有效的防治区块交易篡改问题,如果交易区块被篡改后,区块的下一个区块中的Pre-hash指针也要进行修改,修改一个链上节点还不够,要修改最少超过51%的节点才有可能成功,而且还要在约定的10分钟内下个区块被生产出来前完成才能被整链接收。
共识算法
区块链中有个很重要的模块是共识算法,目前各个平台各个业务场景使用的共识算法也是不一样的,例如比特币使用工作量证明PoW(Proof of Work),以太坊即将转换为权益证明PoS(Proof of Stake),比特股使用授权权益证明DPoS(Delegated Proof of Stake)。
POW:Proof of Work,工作证明。
比特币在Block的生成过程中使用了POW机制,一个符合要求的Block Hash由N个前导零构成,零的个数取决于网络的难度值。要得到合理的Block Hash需要经过大量尝试计算,计算时间取决于机器的哈希运算速度。当某个节点提供出一个合理的Block Hash值,说明该节点确实经过了大量的尝试计算,当然,并不能得出计算次数的绝对值,因为寻找合理hash是一个概率事件。当节点拥有占全网n%的算力时,该节点即有n/100的概率找到Block Hash。
POS:Proof of Stake,股权证明。
POS:也称股权证明,类似于财产储存在银行,这种模式会根据你持有数字货币的量和时间,分配给你相应的利息。
简单来说,就是一个根据你持有货币的量和时间,给你发利息的一个制度,在股权证明POS模式下,有一个名词叫币龄,每个币每天产生1币龄,比如你持有100个币,总共持有了30天,那么,此时你的币龄就为3000,这个时候,如果你发现了一个POS区块,你的币龄就会被清空为0。你每被清空365币龄,你将会从区块中获得0.05个币的利息(假定利息可理解为年利率5%),那么在这个案例中,利息 = 3000 * 5% / 365 = 0.41个币,这下就很有意思了,持币有利息。
DPOS:Delegated Proof of Stake,委任权益证明
比特股的DPoS机制,中文名叫做股份授权证明机制(又称受托人机制),它的原理是让每一个持有比特股的人进行投票,由此产生101位代表 , 我们可以将其理解为101个超级节点或者矿池,而这101个超级节点彼此的权利是完全相等的。从某种角度来看,DPOS有点像是议会制度或人民代表大会制度。如果代表不能履行他们的职责(当轮到他们时,没能生成区块),他们会被除名,网络会选出新的超级节点来取代他们。DPOS的出现最主要还是因为矿机的产生,大量的算力在不了解也不关心比特币的人身上,类似演唱会的黄牛,大量囤票而丝毫不关心演唱会的内容。
PBFT:Practical Byzantine Fault Tolerance,实用拜占庭容错算法。
PBFT是一种状态机副本复制算法,即服务作为状态机进行建模,状态机在分布式系统的不同节点进行副本复制。每个状态机的副本都保存了服务的状态,同时也实现了服务的操作。将所有的副本组成的集合使用大写字母R表示,使用0到|R|-1的整数表示每一个副本。为了描述方便,假设|R|=3f+1,这里f是有可能失效的副本的最大个数。尽管可以存在多于3f+1个副本,但是额外的副本除了降低性能之外不能提高可靠性。
区块链带来了什么?解决了什么问题?
上面介绍了区块链的一些概念,那么为什么区块链会如此火爆,并且被认为是颠覆性的,我认为有以下几点原因:
1)区块链中的区块地址可以代表任何有价值的东西,比如说,股权、债权、版权、投票权、专利权等,可以代表一切你可以想象的到的有价值的东西。因为区块地址可以实现权益的数字化,而资产的数字化,是未来5~10年一个巨大的趋势。
2)区块链协议拥有自我激励机制,市场经济为什么能够促进资本主义社会发展那么好,其中最重要的是激励机制,每个人都在为自己挣钱,无论是打工、创业,盈利、上市,但客观上却推动了整个市场的繁荣,构建一个可以正向循环的,促进国家GDP、全球GDP增长的一个系统。因此在区块链体系中可以让上下游能够在这个生态下快速野蛮生长,很重要的因素也是激励机制,为什么那么多公司愿意去参与竞争(挖矿),因为他们能够拿到奖励,能够拿到回报,就有动力去完成整个区块链生态的不断发展。
区块链那么具有颠覆性,那么它帮我们解决了什么问题?
笔者认为其实就是解决了一个核心问题互联网参与者之间的监视和信任问题
。
目前传统的方法很难解决互联网参与者之间的监视和信任问题,在互联网上各个参与者之间是很难实现跨机构或个人进行交易监控的,所以这就产生了互相不信任。自己的账本在交易时容易被篡改,如果产生参与者间协作就会带来额外的工作量和中介等额外开销和成本,业务合同的分散也导致了合同有效性很弱,业务本身依赖于一个或几个核心机构,如果出现攻击、系统故障等问题将导致所有参与者损失。
在现实社会我们有多少产物是为了解决人与人、人与企业、企业与企业之间的信任问题?仔细想想周围很多公司和产品都是为了解决信用问题而诞生,供应链系统解决了上下游和核心企业之间的信任问题,swift组织解决了进出口公司、银行之间的信任问题,Verisign解决了客户端和服务器端之间证书认证问题等等,这些在有了区块链做为底层技术后都可以得到比较完美的解决。下一篇文章我也会具体描述下区块链可以使用的业务场景和对现有行业带来的颠覆性的变化。
核心功能模块
那么如果要实现一个区块链系统需要实现哪些功能?区块链底层具体包含了哪些模块呢?下面这张功能架构图中可以看到需要饱含下面这些功能模块,不过我们在具体的使用过程中可以根据实际情况进行模块筛减和替换。
实现一个区块链至少分为三层,这里不考虑类似钱包这些外围的配套产品,最底层是一些通用的基础模块,比如基础加密算法,网络通讯库,流处理,线程封装,消息封装与解码,系统时间等,类似我们常见的框架中的common库。
中间层是区块链的核心模块,一般包含了区块链的主要逻辑,如P2P网络协议,共识模块,交易处理模块,交易池模块,简单合约或者智能合约模块,嵌入式数据库处理模块,钱包模块等等;
我们细说下各个核心模块:
-
P2P网络协议模块
dns seed :dns seed 由区块链的社区成员维护, 其中一些提供动态的dns seed服务,通过扫描网络自动获取活跃的节点IP地址,其中一些提供静态dns seed, 这些种子是手动添加的。通过类似爬虫的功能去嗅探网络的节点。
discovery node :服务发现节点
address book:记录整个区块链上的所有地址的地址簿,每个节点都要存储一份地址簿,用于广播消息到其他节点
ping pong keepalive :通过pingpong来判断p2p网络中节点是否有效的一种心跳检测机制,可以通过多种方式来实现。
shake-hands:握手机制,区块链中需要有一套握手机制,类似http、https的多次握手机制,通过握手来保证P2P连接的可用性。
data-stream transfer :数据传输机制,在P2P网络中需要定义一套节点之间的数据传输机制,在超级账本开源项目中的数据传输协议是PB,在实现过程中可以根据自己习惯的协议来实现。
membership:成员管理提供会员注册,身份校验,交易审计等功能,对于联盟链来说成员管理还涉及到交易权限隔离等访问控制功能。
-
交易模块
smart contract(可选):对于存在智能合约的业务场景是需要实现智能合约的功能,智能合约需要按照业务场景需求来完成合约的智能规约,根据业务场景的复杂度会导致智能规约难度的变化。
merkle tree:需要在交易模块中维护Merkle树,Merkle其实就是一棵平衡二叉树,但是每个节点保存的节点值为所有子节点的交易hash,通过Merkle树能够提高查找效率,当然对于一些简单的区块链系统也可以没有merkle树结构,通过链表结构或者单值节点来实现。
transaction records :当然在交易模块还要纪录所有的交易记录,但是区块链中的交易记录管理功能和一般系统还是有差异的,并没有完整的CRUD,区块链一般只提供查询和插入交易记录的功能接口。
indexs of ledgers:账本索引,通过账本索引能够比较方便的找到相关交易。
-
加密模块
hash:整个区块链中很多地方都用到了hash算法,最重要的是在标示一个区块唯一性的时候会对每个区块在生成出后都会分配一个sha256后的散列值,具体的算法每个区块链可以根据自己的应用场景要求来设计。
非对称加密:非对称加密在区块链中主要是用于对交易使用私钥进行加密,其他节点通过地址公钥去校验交易的合法性,类似做了一个签名验签的过程,这里的非对称算法包括密钥长度其实也是开发者根据业务场景来设计的。
-
共识算法模块
共识算法其实上面也提到了,具体使用什么共识算法也是根据具体业务场景来实现,不同的共识算法应对不同的业务场景。其实共识算法是整个区块链中非常核心的一部分,共识算法的好坏涉及到整个区块链产品的激励机制和未来生态发展。
共识算法核心要解决以下问题,目前主流的PoW、PoS这些共识算法也都是为了解决这些问题:
- 每个节点交换数据过程不被篡改;交换历史记录不可被篡改;
- 每个节点的数据会同步到最新数据,且承认经过共识的最新数据;
- 基于少数服从多数的原则,整体节点维护的数据本身客观反映了交换历史。
-
管理模块
user interface:通过封装各种基于Restful 的webservice api来访问各种接口。
setting:提供各种基础设置功能。
-
钱包模块(可选)
钱包属于外围模块,一般主要实现了hash地址管理,key校验、角色管理、白名单、黑名单管理等,钱包的实现方式也多种多样,具体根据业务场景的不同来实现。
最上面一层,往往都是基于Json RPC的交互模块,基于Json-RPC,我们还可以做出更好的UI界面,也可以是一个 restful web-service。
开源区块链系统
比特币
比特币是整个区块链世界最经典的实现,比特币的协议层是用C++实现的,官方钱包是Qt写的,还有很多第三方钱包用Python或者Ruby等语言实现。
以太坊
https://github.com/ethereum/pyethapp
著名的以太坊提供了多种语言的实现方案Go、Python、Java实现了区块链的功能,虽然以太坊发生过The DAO事件,但是代码还是有很多可取之处,可以拿来学习。
超级账本
https://github.com/hyperledger
超级账本项目是Linux基金会主导开发的,是目前链圈最火的区块链开源项目。该项目试图为新一代的事务应用创建一种开放的分布式账本标准,支持许可式区块链。部署方式可docker化,支持用Go和JavaScript开发智能合约。它采用PBFT分布式算法,网络编程方面用gRPC来做P2P通讯,使用 Protocol Buffer来序列化要传递的数据结构。
总结
本篇的内容其实还是挺多的,里面每一块都可以拿出来单独写一篇,这篇还是有点偏技术,对于程序员应该都能看懂,如果你是没有接触过区块链的程序员看看这篇应该能够快速知道区块链需要用到的技术有哪些,心里大致也会有个概念,希望本篇能够成为程序员入门区块链的好文章。