从"斗地主"开始一步一步学习区块链

本文以斗地主游戏为例,介绍区块链的分布式记账系统。从集中式记账的问题出发,引出区块链的去中心化记账模式,解释哈希加密算法和共识机制在防止篡改和保证数据透明性中的作用。并通过编写简单的区块链代码,实际体验区块链的工作流程。
摘要由CSDN通过智能技术生成

区块链由浅入深(第1部分):从记账开始

“If you can not explain it simply,you don’t understand it。”
“如果你不能把一个技术很简单的讲出来,实际上是你没有吃透它。”

前言

区块链技术是最近几年的热门技术,许多人开始了解学习它,但是它毕竟是一个有一定难度的技术,要深刻理解需要一定的融会贯通能力,要不就只能“空学习了一大堆名词,而难探其究”。
本文试图从最简单的生活场景开始,一步一步通过例子来描述区块链的原理;
对于想准确理解的技术性读者,会将用到的技术中英文属于对照列出,避免很多文章中翻译不一致造成的概念混淆。
对于有一定编码能力的读者,我们提供了示例性的代码,你可以通过下载运行,一步一步更加直观的理解区块链在计算机上的实现方式,完成你的第一个可以实际运行的区块链代码示例。

先从一个打牌游戏开始

话说张王李三个好基友最喜欢的娱乐就是“欢乐斗地主”,今天周末他们又聚在一起,准备好好干个天昏地暗。
在这里插入图片描述

规则还是老样子:输赢基数一元钱,炸弹翻倍。
打牌是在小张的家里,每次小张都是让自己的上小学的弟弟张二宝过来记账,张二宝虽小,但是是比较细心,字写得好看,冰雪聪明。
第1局,小李是地主,结果输掉了,他就分别给小张小王各1元钱; 开始第2局……
三局之后,张二宝在纸上的记账如下:
在这里插入图片描述

记账的问题来了

三局过后,小张看到账本一盘算,还是自己赢的多,上次也是自己赢了,禁不住手舞足蹈起来,甚至还在别人洗牌间隙表演起来了自己在抖音上新的“嘟嘟舞”,然而意想不到的事情发生了:她竟然把刚刚泡好的一杯咖啡给打翻了,更重要的是这杯咖啡竟然就倒在了记账的便签纸上,一下子糊掉了,什么都看不清了…
在一阵慌乱之后,大家都开始了思索:
小李在心里嘀咕了: 为什么我每次打牌都是输呢?是不是记账的张二宝同学有舞弊嫌疑,给哥哥记录假账的可能?
小王是个没有记性的人,每次打几把,他都要问记账的把账单拿过来看看,心里琢磨自己赢多少或者输多少?次数多了,有点被记账的张二宝嫌弃,也有点不爽。
记账员张二宝也不开心了,每次都给他们服务,只能得到一个棒棒糖的奖赏,而且又一次自己去上个厕所漏记了一次,被他们发现教训,心里不爽,借着这个机会,就推掉算了。
小张是个机灵的人,他早也看到了两位的心思,突然想起网上有关区块链的介绍,“区块链的基础核心是分布式记账系统,具备不可篡改、不可抵赖,公开透明的特点”,为什么不用用区块链技术呢?想到这里他开始说给大家如此这般介绍一下,大家一听,都拍手称赞,新的记账模式开始了:

在这里插入图片描述

小结:他们开始各自记账

原来的模式下:所有的记账都是一个集中式的,由张二宝同学集中记账,所有的记录以中央记录的账本为准,每一个参与者(打牌的人)要想了解记账信息,就要向集中的账本查询。 在异常的情况下会出现账本丢失损毁,所有信息就会丢失; 还会出现集中记账系统出现错误时候(漏记,记错,或者有意篡改数据的可能)。
新的各自记账的模式: 取消了集中记账的角色(张二宝),在每局打完之后,三个人就分头各自记账并各自保存账本。这样的两个最明显的益处是: 可以防范集中记账奔溃的问题,而且每个人的账本完全一样,公开透明,每个人可以随时查看他自己的信息。

blockchain is a distributed, decentralized, public ledger.
区块链是一种分布式的,去中心化的,公开的记账系统。

读到这里,恭喜你,你已经了解大致区块链是怎么运作了。
接下来我们将看看新的模式下有什么新的问题,如何解决它。

区块链由浅入深(第2部分):新的问题和解决之道

“A solution of the problem may also bring new problems.”
“一个问题的解决也可能随之带来新的问题。”

记录更多的信息

为了让信息更加准确和完备,每局打完牌后我们可以记录更多的信息,如下是第一局结束后的记录:
在这里插入图片描述
其中:
“No”来标记这是第几局,是第一局,所以写 “No:1”;这个数据有利于准确的记录局数,也便于最终的核对
接下来是具体的输赢数据,第一局,小张赢了1元,小李赢了1元,小李输了2元,依次记录;
“时间”用来记录这局结束后记账的时间,我们精确到秒,例如“2020-03-26 16:42:08”
“计数器”记录的是节点计算机需要计算多少次哈希函数,才能得到符合设定目标的哈希值(后面详解)。
“哈希”记录的是本局(本区块)记账信息的一个哈希计算结果(后面详解)。
“前哈希”记录的是上一局(上一个区块)记账信息的一个哈希计算结果(后面详解)。
每个区块通过记录前面一个区块中的哈希值,把整个区块链接起来,形成了“区块链”。
注意:后面将要提到的 “区块”对应到这里就是每一局结束后的交易记录(记账信息)。
后面将要提到的 “节点”对应到这里就是每一个单独的记账者(本例子中有3个人各自记账,就有3个节点,节点数也可以和交易参与者数量不一致)。

在这里插入图片描述

哈希(Hash)加密算法

哈希函数(Hash Function),也称为散列函数或杂凑函数。哈希函数是一个公开函数,可以将任意长度的消息M映射成为一个长度较短且长度固定的值H(M),称H(M)为哈希值、散列值(Hash Value)、杂凑值或者消息摘要(Message Digest)。它是一种单向密码体制,即一个从明文到密文的不可逆映射,只有加密过程,没有解密过程。
通俗的将,就是无论输入是什么数字格式、文件有多大,输出都是固定长度的比特串。例如SH256算法为例,无论输入是什么数据文件,输出就是256bit(64位16进制数)。
理论上讲,计算机上的任意一段信息,都可以利用哈希函数来生成 一个64位的不重复的16进制字符串。只要稍微更改一下信息,生成的哈希字符串就不一样了,例如:
Charles 2020 哈希值是:d93a6a24e8dee43aa1b3303a54f518420405294c4296851e5634e9532ef179c8
charles2020 哈希值是:14a3ab2a3f64dee43b5f1f37ae911e6aae86ffc501cbec00f12f01f928b9a73
“《人民日报》截至北京时间25日17时,中国以外新冠肺炎确诊病例达到332331例” 这句话的哈希值是:a579eedb7cd380b6c80ce417449a8fea8d62f4a0bd37266e852ee4b5dd1292df

在这里插入图片描述
我们再回到我们前面的区块记录中:
哈希值 记录的是当前块中数据字符转拼接起来,通过哈希算法,得到当前区块的哈希值,这个哈希值也可以叫做当前区块的签名,具备唯一性。就是当区块中数据如果发生了任何变化(例如被篡改等)那么重新计算出来的哈希函数值就会和表中记录的哈希值不相等,从而引起当前区块处于“无效”。
如果有的节点想篡改数据,他先修改了区块中的数据,然后按照哈希算法再算出新的哈希值,再用新计算的哈希值更新当前块的哈希值,使得当前块看起来“有效”,但是由于后面每个区块都会依次记录前一个区块的哈希值,现在发现前面的区块哈希值发生了变化,就会引起从这个区块及以后的所有的区块标识为“无效”。

共识机制:找出能把当前区块链接到链上的人

刚打完一局,例如第一局中,小李自己作为地主,输了2元,需要给小张和小王各自1元。这一点在大家没有异议的情况下,可以分头记录在自己的账本上。
但是如果参与者众多(成千上万的情况),最好的方式是,先由其中一个人例如小张记账,然后把记账拿给大家看,大家照着这个记账再抄写一遍到自己的账本上。我们再这里权且称这个人(小张)为本区块(局)“有权记账者”
那么问题来了?这个有权记账者是怎么产生的?
要知道在区块链中每个节点的位置是完全相同的,那么说有权记账者是怎么选出来? 这个可以有各种办法,例如抽签,例如投票,例如按照年龄,也可以设计一个简单问答来选出“有权记账者”但是在计算机实现上,考虑到计算机最大的资源是“计算机的运算能力”,我们就设定一个规则如下:
每一局结束,谁的计算能力最强,谁来做“有权记账者”,这个是就是把这个块链接到已经有的链上,让当前这个块有效。
要考察谁的计算能力最强,我们出的题目是:“计算每个区块的哈希值,为了增加难度,哈希值需要前面N位为0”
如果假定N设定为2。则计算过程为:
在这里插入图片描述
谁先计算出来,谁就是把这个区块链接到主链上的人。链接后区块有效,系统通知其他人员复制到自己的账本,本次记账完成,开始下一局打牌。
如果该节点计算了101次(None值=100),他的工作量就是100。
这就是区块链中的共识机制中的POW (Proof of Work) 工作量证明.

PoW工作量证明 及其它

在区块链系统当中,没有一个像银行一样的中心化记账机构,保证每一笔交易在所有记账节点上的一致性,即让全网达成共识至关重要。区块链共识机制解决的就是这个问题。
目前区块链主要的共识机制有工作量证明机制PoW (Proof of Work)和权益证明机制PoS (Proof of stack)。
PoW通过评估你的工作量来决定你获得记账权的机率,工作量越大,就越有可能获得此次记账机会。
PoS通过评估你持有代币的数量和时长来决定你获得记账权的机率。这就类似于股票的分红制度,持有股权相对多的人能够获得更多的分红。
还有一种是DPOS,它与POS原理相似,只是选了一些“代表”。 与PoS的主要区别在于节点选举若干代表人,由代表验证和记账。
随着技术的发展,未来可能还会诞生更先进的共识机制。

本章小结

共识机制(consensus):区块链中的节点由于在同一时间会有时间上的延迟和动作的不同,需要一套公平的规则来规范这些节点,使得整个区块链系统顺利地运行下去。
从本质上来讲,共识机制就是决定了谁在区块链系统中有权负责某一个新区块链接到主链上的作用。

区块链由浅入深(第3部分):简单的区块链代码

*“Genuine knowledge comes from practice”
“实践出真知”

通过前面两个章节,我们已经对于区块链的概念以及运行机制做了大致了解,接下来是实际动手通过一个编程来实际体验了。

需要具备的编码知识

• 面向对象的编码基本知识。
• Java编程,编译及运行
• 加密的相关知识

代码实现:区块类-PokerBlock

“区块类”中存放每次区块的信息(记账信息,解密信息,链接信息等),我们在该类中存放6个值:

data -当前区块的说明信息,第几局。
xiaozhang - 记录小张在当前局中的输赢数量
xiaowang - 记录小王在当前局中的输赢数量
xiaoli - 记录小李在当前局中的输赢数量
strDateTime - 记录当前交易发生的时间
nonce - 记录当前区块的工作量(即通过多少次hash运算最后得到了符合条件的当前区块的哈希值) hash - 当前区块的哈希值
previousHash - 前一个区块的hash值

/**
 * @Description:    简单的区块链示例:扑克牌斗地主记账。
 * 
 * @author          Charles (yonglin_guo@hotmail.com)
 * @version         V1.0  
 * @Date            03/19/2020
 */
package com.janny.pokerblockchain;
 
import com.janny.pokerblockchain.JannyUtil;

/**
 PokerBlock 区块类
 “区块类”中存放每次区块的信息(记账信息,解密信息,链接信息等)
 */
public class PokerBlock {
   
	

	//每个区块存放的数据信息,这里我们存放的是第几局,以及三个人的在当前牌局的输赢数量。
	private String data; 	
	private int xiaozhang; 
	private int xiaowang; 
	private int xiaoli; 
	
	
	//时间字符串
	private String strDateTime;
	
	/* 	挖矿者的工作量证明PoW。
	 *	在这里指需要经过多少次哈希运算才能得到满足条件的哈希值
	 *	
	 */	
	private int nonce;
	
	// 当前区块的哈希值;	
	public String hash;
	
	// 前一个区块的hash值;	
	public String previousHash; 
	
	
	
	//构造方法  
	public PokerBlock(String data,int xiaozhang, int xiaowang, int xiaoli, String previousHash ) {
   
		
  • 14
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值