从记账开始
“如果你不能简单地解释,那你就不明白了。”
“如果你不能很简单地说出一种技术,那你实际上是在吃它。”
区块链技术是近年来流行的技术。许多人开始理解和学习它。然而,这毕竟是一项有一定难度的技术。要深刻理解它,我们需要有一定的驾驭能力。否则,我们只能“学了很多虚无难懂的术语”
本文试图从最简单的生活场景出发,通过实例,逐步阐述区块链的原理。
对于希望准确理解的技术读者,他们会列出中英文使用的技术,以避免许多文章翻译不一致造成概念混乱。
对于具有一定编码能力的读者,我们提供示例代码。您可以下载并运行代码,逐步了解区块链在计算机上的实现,并完成第一个实用的区块链代码示例。
从纸牌游戏开始
也就是说,张、王、李三个好朋友最喜欢的娱乐就是“开心地斗地主”这个周末,他们再次聚在一起,准备在黑暗中做好工作。
规则还是一样的:输赢基数是1元,**翻倍。
打牌在小张家里。小张,每次都问他弟弟是谁,都在上小学。张二宝虽然个头小,但比较细心。他的笔迹既好看又聪明。
第一场比赛,小李是房东,但输了,他给了小张和小王各1元钱
三场比赛结束后,张二宝纸上记账情况如下:
记账的问题来了
三局过后,小张看到自己在书中赢了很多书,**一次他赢了。他禁不住又跳又跳。他甚至在洗牌室表演了他的新提克托克舞。但意外的事情发生了。他甚至打翻了一杯刚煮好的咖啡。更重要的是,咖啡真的掉下来了。记账笔记纸上,一下子粘掉了,什么看不清
一阵忙乱之后,大家都开始想:
小李心里嘀咕着:为什么每次打牌都输?有没有可能是学簿记的张二宝涉嫌为弟弟作弊?
小王是个没有记忆的人。每次打几场,他总是让簿记员拿着账单看一看,琢磨自己到底赢了多少,输了多少?很多时候,有点记账本领的张二宝都不喜欢。他也有点不开心。
簿记员张二宝不高兴。他每次都招待他们,只得到一个棒棒糖奖励。而且,他上了厕所,又一次失去了记忆。当他被发现时,他很难过。他借此机会放弃了。
小张是个聪明人。他早就看到了他们的想法,突然想起了互联网上区块链的引入。”区块链的基本核心是分布式会计系统,它具有不可篡改、不可抵赖、开放透明的特点。为什么不使用区块链技术?想到这里,他开始说他想把它介绍给你。我们一听到,他们都拍手称赞。新的会计模式开始了:
小结:他们开始分别记账
原模式下:所有记账均为中心化记账,由张二保中心化记账。所有记录以中央记录为准。如果每个参与者(打卡人)想知道记账信息,应查询中心化账簿。在非正常情况下,账簿会丢失和损坏,所有信息都会丢失;中心化核算系统也会出现错误(遗漏、错误记录或故意篡改数据)。
独立记账的新模式:取消了中心化记账(张二保)的作用。每轮结束后,三人分别记账,各自记账。最明显的两个好处是:可以防止中心化记账的崩溃,而且每个人的账簿完全一样,公开透明,每个人都可以随时查看自己的信息。
区块链是一种分布式、去中心化的公共账本。
区块链是一个分布式、去中心化和开放的会计系统。
读完这篇文章,恭喜你,你对区块链的运作有了一个大致的了解。
接下来,我们来看看新模中存在哪些新问题,以及如何解决这些问题。
A602A606号
新问题及解决方案
“问题的解决也可能带来新的问题。”
“问题的解决也可能带来新的问题。”
记录更多信息
为了使信息更加准确、完整,我们可以在每场比赛结束后记录更多的信息,具体如下:
其中:
“否”是用来标明局数和首轮,所以写“1号”;这一数据有利于准确记录比赛场次,也便于最终核实;
其次是具体的输赢数据。第一轮,小张赢了1元,小李赢了1元,小李输了2元,依次录音;
“时间”用于记录游戏结束后的记账时间,我们精确到秒,如“2020-03-26 16:42:08”
“计数器”记录节点计算机需要计算哈希函数的次数,以获得满足设定目标的哈希值(稍后将详细解释)。
“Hash”记录局会计信息的哈希计算结果(该块)(稍后详细解释)。
“前散列”记录上一轮(前一块)的记帐信息的哈希计算结果(稍后详细说明)。
每个块通过记录前一个块中的哈希值来链接整个块以形成“区块链”
注:后面提到的“区块”对应于每轮交易结束后的交易记录(会计信息)。
后面提到的“节点”对应于这里的每个单独记账人(在本例中,如果有三个人分别记账,则有三个节点,节点的数量也可能与交易参与者的数量不一致)。
哈希加密算法
散列函数,也称为散列函数或散列函数。散列函数是一种公共函数,它可以将任意长度的消息M映射成一个短的固定值H(M),称为散列值、散列值、散列值或消息摘要。它是一种单向密码体制,即从明文到密文的不可逆映射,只有加密过程,没有解密过程。
一般来说,无论输入的数字格式是什么,文件有多大,输出都是固定长度的位串。例如sh256算法,无论输入什么数据文件,输出的都是256位(64位十六进制数)。
理论上,计算机上的任何信息都可以使用哈希函数生成一个64位不重复的十六进制字符串。只要稍微改变一下信息,生成的哈希字符串就会不同,例如:
Charles 2020哈希值为:
d93a6a24e8dee43aa1b3303a54f518420405294c4296851e5634e9532ef179c8
charles2020哈希值为:
14A3AB2A3F64DEE43B5F1F37AE911E6AE86FFC501CBEC00F12F01F928B9A73
经《人民日报》诊断的新冠状病毒肺炎截至25时在北京17时,我国已达332331例,这句话的散列值为a579eedb7cd380b6c80ce417449a8fea8d62f4a0bd37266e852ee4b5dd1292df(注:《人民日报》于2020年3月25日发布)。
让我们回到之前的区块记录:
哈希值记录当前块中的数据字符,通过哈希算法获得当前块的哈希值。这个哈希值也可以称为当前块的签名,并且具有唯一性。如果块中的数据发生变化(如被篡改),重新计算的哈希函数的值将不等于表中记录的哈希值,从而导致当前块“无效”
如果他想用新的哈希块计算出当前哈希值,那么他就用新的哈希值来修改当前哈希块中的值。但是,由于每个后续块依次记录前一个块的哈希值,因此发现前一个块的哈希值已更改,这将导致来自该块的所有块被标记为“无效”
共识机制:找出谁可以将当前区块链接到链
以刚结束一场比赛为例,在第一场比赛中,作为房东的小李输了2元钱,需要给小张和小王各1元钱。这一点在没有异议的情况下,可以单独记入自己的账本。
但是,如果参与者很多(上千个案例),**的办法是让其中一个参与者,比如一个小表格,记录下账户,然后展示给每个人,然后**到自己的账簿上。这里我们称此人(小张)为本区(局)的“授权簿记员”
所以问题来了。。。?这个有权记账的人是怎么产生的?
要知道区块链中每个节点的位置完全相同,如何选择簿记员?有很多方法可以做到这一点,比如抽签、投票,例如,根据年龄,或者设计一个简单的问题和答案来选择“簿记员”但是,在计算机实现方面,考虑到计算机**的资源是“计算机的算力”,我们制定了如下规则:
每场比赛结束后,谁拥有最多的算力,谁将成为“簿记员”,就是要将这个区块与现有的区块链连接起来,使当前区块有效。
要找出谁的算力最强,标题是:“要计算每个块的哈希值,为了增加难度,哈希值的前n位应该是0。”
如果n被设为2。计算过程如下:
谁先计算它,谁就把这个区块链接到主链上。链接后,冻结生效,系统通知其他人员**到自己的账簿上。这个簿记完成,下一轮扑克牌开始。
如果节点计算101次(none=100),则其工作负载为100。
这是区块链共识机制中pow(工作证明)工作量的证明。
POW工作量认证及其他
在区块链系统中,没有银行这样的中心化记账机构。保证所有计费节点上每一笔交易的一致性,即使整个网络达成一致,是非常重要的。区块链共识机制解决了这个问题。
目前,区块链的共识机制主要有pow(工作证明)和POS(堆栈证明)。
POW评估您的工作量,以确定您获得簿记权的机会。你做的工作越多,你就越有可能得到记账的机会。
POS通过评估您持有代币的数量和时间长度来确定您获得记账权的机会。这类似于股票的分红制度。持有更多股份的人可以得到更多的红利。
另一个是dpos,它与POS的原理类似,只是选择了一些“代表”与POS的主要区别在于节点选举多个代表,由代表进行验证和记录。
随着技术的发展,未来可能会出现更先进的共识机制。
本章摘要
共识机制:区块链中的节点由于时间延迟,同时又有不同的动作,需要一套公平的规则来规范这些节点,使整个区块链系统能够平稳运行。
本质上,共识机制决定了谁有权对区块链系统中与主链相连的新区块的角色负责。
简单区块链代码
*“真正的知识来自实践”
“真正的知识来自实践”
通过前两章,我们对区块链的概念和运作机制有了大致的了解。接下来,我们将通过编程来获得实际经验。
需要编码知识
具有面向对象编码的基本知识。
Java编程、编译和运行
加密相关知识
代码实现:block类pokerblock
“块类”存储每个块的信息(记帐信息、解密信息、链接信息等),我们在该类中存储六个值:
数据-当前块的描述信息,轮数。
小张-记录张在当前游戏中的输赢次数
小王-记录王在当前游戏中的输赢次数
小李-记录小李在当前游戏中的输赢次数
Strdatetime—事务的当前事务时间
Nonce-记录当前块的工作负载(即执行了多少个哈希操作以获得满足条件的当前块的哈希值)hash-当前块的哈希值
Previoushash—上一个块的哈希值
/***@说明·区块链的一个简单例子:打牌和记账。**@作者查尔斯;(吴永林)[email protected])*@版本V1.0;* @日期:2020年3月19日*/套餐;com.janny.poker区块链;导入;com.janny.poker区块链. {/nyutil数据块存储在每个类的公共信息块中。在这里我们存储游戏编号和当前游戏中三个玩家的输赢次数。private string数据private-int-Xiaowang-private-int-xiaong-li//time-string-private-string-strdatetime/*矿工工作量的证明功率。这里,它指的是要获得满足条件的散列值需要多少个散列操作*私有私有私有内部私有私有私有私有私有私有私有私有私有私有私有私有私有私有;私人私人私人私人私人私人私人私人私人私人私人私人国际私人私人私人国际私人私人国际私人私人私人国际私人私人私人国际私人私人私人私人私人国际私人私人私人私人私人私人国际私人私人私人私人私人国际私人私人私人国际私人私人私人私人国际私人私人私人私人私人国际私人私人私人私人国际私人私人私人私人国际私人私人私人私人国际私人私人私人私人国际私人私人私人国际私人私人私人私人国际私人私人私人私人国际私人私人私人私人国际私人私人私人私人国际私人私人私人私人国际私人私人私人私人私人国际私人私人私人私人国际私人私人私人私人私人国际私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人私人;private private int private private//构造方法Public pokerblock(string data,int Xiaozhang,int Xiaowang,int Xiaoli,string previoushash){;此数据;=数据;这位是小张;=小张;我是小王;=小王;这位是小丽;=小丽;以前的哈希值;=上一个哈希;本标准时间;=(newJannyUtil()).getCurrentDateStr();这个。散列;=calculatehash();};//根据当前块Public string calculatehash(){stringcalculatehash=(newJannyUtil())的信息内容计算新的哈希值。appSha256(data+整数.toString(小张)+;整数.toString(小王)+;整数.toString(小丽)+标准时间+;整数.toString(nonce)+previousHash;);返回计算哈希值}/*;这里的“挖矿”过程是指需要进行多少次哈希操作才能得到满足条件的哈希值。条件具有参数Differentiation设置,例如:如果Differentiation的值为2,则计算的哈希值的前两个字节应为“00”;如果不是,则nonce的值增加1以继续计算;///Public void mineblock(int diffculture){/难度值,难度值越大,难度值越大,字符串目标字符串的计算量越大;目标字符串目标字符串字符串目标字符串字符串目标字符串字符串;目标字符串字符串目标0000 while(!哈希.substring(0,难度)。equals(target)){nonce++;hash;=calculateHash();System.out.println(quot;!POW工作。。。quot;+quot;nonce:quot;+,nonce+quot;:哈希:quot;+哈希);}System.out.println(quot;!!!当前节点POW完成,并创建一个新的块:quot;+hash);}}
代码实现:公共工具类-jannyutil
“通用工具类”是使用各种加密算法、字符串转换算法等公共函数。注意,为了将block对象打印为字符串以供观察,我们可以用ON string对象替换block对象。
注意:确保gson-2.8.6.jar公共类库已下载并包含在类的编译路径中
/***@说明·区块链的一个简单例子:打牌和记账。**@作者查尔斯;(吴永林)[email protected])*@版本V1.0;* @日期:2020年3月18日*/套餐;com.janny.poker区块链;导入;java.text.SimpleDateFormat;导入;java.util.Date;导入;java.util.ArrayList;导入;java.baseutil.64版;导入;java.security.Key;导入;java.security.MessageDigest;//您需要下载并确保gson-2.8.6。Jar在类路径中导入;com.google.gson网站. gsonbuilder;/**tool class*获取当前时间的字符串格式。对于字符串的数字签名,它将对象更改为ON格式的数据,并返回难度字符串targetnbsp*@作者查尔斯;**/public静态字符串字符串getcurrent字符串getcurrent字符串字符串;getcurrent string getcurrent和GetCurrentDate简单日期格式格式化程序新单纯形格式(quot;yyyyyy-mm-dd HH:mm:mm:ssquot;);字符串公共静态字符串;字符串日期字符串;格式化程序.format(newDate());return datestring}/*计算字符串*的哈希值;MessageDigest.getInstance(quot;md5quot;);MD5生成128位(16字节)哈希值*;MessageDigest.getInstance(quot;sha-1quot;);SHA-1生成160(20字节)位字符串*;MessageDigest.getInstance(quot;sha-256quot;);SHA-256;生成一个256位(32字节)字符串*/公共静态字符串appsha256(字符串输入){trymessage digestdigest=MessageDigest.getInstance(quot;SHA-256quot;);字节[]哈希=;文摘.文摘( 输入.getBytes(quot;UTF-8quot;));StringBuffer-hexString=new-StringBuffer();表示int-i=0;哈希长度;i++){String-hex-hex=;整数.toHexString(0xff哈希[i]);如果(六边形长度()===1)1);十六进制字符串.append(#39;0#39;);十六进制字符串.append(十六进制);}返回;六角字符串.toString();}catch(exceptionE){thrownewruntimeException(E);}//返回ON格式的数据以供打印。Public Public静态字符串Public static string geton(object o){return return new new gsonbuilder()。setPretyPrinting()。创建()。创建()。Togson(o);}//返回难度字符串目标,//返回难度字符串目标,如难度5,将返回难度字符串目标,例如难度5将返回“00000”Public静态静态字符串字符串字符串;getDefiltFiltFiltcultyString字符串(intreturn;return返回难度字符串目标,例如难度5将返回“00000”Public PublicPublic静态字符串string替换字符串39;039;,0039;;039;//返回难度字符串目标,例如难度5将返回“00000”公共静态字符串getstringfromkey(KeyKey{;return返回return返回return返回return返回return Base64。Getencoder()。编码字符串(key.getEncoded键());}public static void main(字符串[]参数){;System.out.println(quot;Datetime……quot;+getCurrentDateStr());}
代码实现:区块链类扑克区块链
区块链类用于生成区块并将其添加到区块链中,这也可以确定当前区块是否有效。
/***@说明·区块链的一个简单例子:打牌和记账。**@作者查尔斯;(吴永林)[email protected])*@版本V1.0;* @日期:2020年3月19日*/套餐;com.janny.poker区块链;导入;java.util.ArrayList;导入;java.baseutil.64版;导入;java.security.security;//您需要下载并确保gson-2.8.6。Jar在类路径中导入;com.google.gson网站.GsonBuilder;/**区块链类@作者查尔斯;**/Publicclasspokerblockchain{//存储所有区块集Public静态arraylistblockchain=newarraylist();;//挖矿难度,数字越大,Public static int难度越大==4 Public static void main(string[]args){string title=quot; int;Xiaozhang==0;int小王==0;int小丽==0;System.out.println(quot;开始创建第0个区块链:创世区块。。。。quot;);Addblock(Newpokerblock(quot;,Block 0,quot;,Xiaowang,Xiaoli,quot;0quot;));//创世基因块标题==quot;;Xiaozhang==1小王=-2;System.out.println正在创建
块。。。quot;);addblock(新扑克区块(quot;,block 1,quot;,小张,小丽,区块链.get( 区块链大小()-1)。Hash));title=quot;;小张==6小王=-3小丽=-3第二局的-3;System.out.println(quot;正在创建块2。。。quot;);addblock(新扑克区块(quot;,block 2,quot;,小张,小丽,区块链.get( 区块链大小()-1)。Hash));title==quot;;=-4;小王==2;小丽==2;小张==2;System.out.println(quot;正在创建块3。。。quot;);addblock(新扑克区块(quot;,block 3,quot;,小张,小丽,区块链.get( 区块链大小()-1.hash));System.out.println(quot;区块链是否有效:quot;+ischainvalid());string-blockchainon=(Newjannyutil())。Geton(区块链);System.out.println区块链1的第一个哈希值是否正确?“valid block”中前一个块的值与前一个块中“valid block”中的前一个块的值不同;String hashtarget=newString(newchar[differentiation])。Replace(39;039;);//循环区块链检查哈希值:for(intI=1;I lt;区块链大小();i++){currentBlock=;区块链.get(i) ;previoulock=;区块链.get(i-1);//比较当前块等于重新计算的值?如果(!currentBlock.hash.equals( currentBlock.calculateHash()){;System.out.println(quot;当前块哈希值验证错误。。。quot;);return false}//当前块中保存的“上一块哈希值”是否等于前一块中的实际哈希值?如果(!previoulock.hash.equals( currentBlock.previousHash)){;System.out.println(quot;当前块的“前哈希值”检查错误。。。quot;);return false}//检查当前区块是否已添加到区块链中?如果(!currentBlock.hash.substring(0,难度)。等于(hashTarget)){;System.out.println(quot;此区块尚未加入区块链。。。quot;);return;false}@paramnewBlock;*/public静态void addBlock(PokerBlock newBlock){;纽布洛克。雷区(困难);区块链.add(newBlock);}}
操作和测试
代码运行后,它开始创建四个块。
当创建每个块时,POW工作(在比特币中称为挖矿)首先完成。挖矿后,当前区块链接到区块链。开始创建下一个块。
为了便于演示,将难度系数设为2。这样,只能完成几十到几百次的哈希算法。
由于空间限制,一些程序输出被省略。只显示前三个计算和后两个计算的哈希值。
开始创建第0个区块链:Genesis区块;!POW在工作一次性:1#️⃣ C40a984d0d31b85640cd67decf7dbe3ab684765b6bf36bf38e243dc428b2d3fb5!功率工作现状:2#️⃣ 0EEF49B73B88396E474489B69BAEAF6F8089C4C6F07417446B8894D720C6D2A4!功率工作3:现在#️⃣ e0d6bfb8f222fc886802047f62217c0683570f403ca1c6ae1409ac8ba359f150!电源工作时间? 哈希:b9ee001c09cc9dfa8884fb4f1b9447f75e30d7fcea09edf75d71eabaa4b97827!工作中的POW现在:101#️⃣ 00719d3db941650ef3cdcdace527c3deed836ddb0cf6304e759cab4ba237db6ee!!!当前节点POW已完成,并创建了一个新块:00719d3db941650ef3deed836ddb0cf6304e759cab4ba237db6ee正在创建第一个块;!POW在工作一次性:1#️⃣ 18215996f7b6f7041d20b8ea5067040af4eeb2370773de9713a1eca1206a5d3e!功率工作现状:2#️⃣ 01987723af672357a6f50da35c32c996c01b6349c860417776144e0b4c6e91!功率工作现状:3#️⃣ f12614d3c9745d00a5631e3a620cbb472454a92214f27eb3f40a8cb0e9faee88!功率工作现时:58#️⃣ 6929737B2D514807AAD983B02011269491C82FDA46BB60009303046D6607050E!功率工作现在:59#️⃣ 005f83c135d7ae782fe1812706d0f08d27ef9e4aa4ac36103f0a38b3a6aa4779)!!当前节点POW完成,并创建新的块:005f83c135d7ae782fe1812706d0f08d27ef9e4aa4ac36103f0a38b3a6aa4779正在创建第二个块;!POW在工作一次性:1#️⃣ 3F4534B335827D278643DD7EAA43BB255C2095200B27DABDC288470E2DED533!功率工作现状:2#️⃣ Cc32db0f15df81d0eb95780175540d45ab20676375ce29e7f8779500819be1f1!功率工作现状:3#️⃣ f505f201630e52e19807d08337b65142f9679854f72fed7657b8266a64e5e254!工作功率现在:59#️⃣ F3B29379D64E8B6C467EFB7ACA05DF5B0DCFF4EAE2C281BA24A5775AC27EF3!功率工作现在:60#️⃣ 0081BA9C9C548CEA03C5B685637D5C1B3BC2808F5967A32B2A20A1EAFB608B);!POW在工作一次性:1#️⃣ EDA9B63FCD8E3A72D604CC9DDA9EBC26E8EAAA314A9999AC44AFC725B919C7C7!功率工作现状:2#️⃣ 061b3386cdb975311cf48a899ac931371da683bac276823e1726741da4a964db!功率工作现状:3#️⃣ 5A9B65E96F470CFCFCFEC5466FD6F5A687C0A9E59D697AD0FB24D723F7C6B3584C!功率工作现在:347#️⃣ 42727F99CBB4C90E622F9C1E736633555A8ADFF4B4BCBDB13FA4375A4B5184A255!功率工作现在:348#️⃣ 区块链是否有效:真和真数据:数据:数据:“0块”,“小张”:“0”,“小张”:,“小张”:“0”,0,“0”,“小张”:16: 42:07,“nonce”:“101,“hash”:“00719d3db941650ef3cdace527c3eded836ddb0cf6304e7759cab4b4b237db6ee”,“previoushash”:“0”“”“nonce;”“{“data”:“第一个块”,“小张”:“1,“小王”:“1,“小李”:“-2”,strdate2,据《2011年第二次公开DB941650EF3CDACCE527C3deeed836DDB0CF63004E7759E759Cab4B4BBa23DB6DB6DB6EE759CAB4BB4BA223DB6DB6DB6EE EE”,“previoushash”:(“时间”“2020-03-26年2616:42:08:08”,“nonce”:(59,“哈希”59“哈希”005f83c3c135d7ae782f812706d0f0d30f9e4a36103f30a38b3aaaa4779”,“上一次哈希”:(上一次哈希”):00719d39d32db941650ef3cdacce527除832323BA237DB6EE“}{“data”;“second block”,“Xiaozhang”:“and{“data”:“the second block”,“Xiaozhang”:“and”previous hash“:”上一个哈希:“00719d3db941650e27c27c3ded836ddb6ddb0cf6304e79cab4b4ba23db6db6ee”},6,“Xiaowang”:-3,“Xiaoli”:“2020-03-2616:42:08”,“nonce”:60,“hash”:“0081ba9c9c548cea03c5b685637d5c1b3bc2808f5967a32b2a20eaeaeaabfb608b”,“前一哈希”:“005f83c135d7ae782fe128fe1812706d0f08d227ef9e4aa4ac36103f0a3a6aa4779”},{“data”:“第三个3:“data”:“第三个3-3aaa4779”},{“data:“data”:”,第三个3-3a6aa4779“},{“data”:“data”:“data”:“data”:“data”:“data”;“data blocks”,“Xiaozhang”:-4,“xiaowang”:-2,“xiaoli”:“2,“strDateTime”:“2020-03-26 16:42:09”,“nonce”:348,“hash”:“00de147c874e856c12145af5302b48a47143e8ee9a185d7e8a7b437b6e1e4”,“上一个哈希”:“0081ba9c9c548cea03c5b685637d5c1b3bc2808f5967a32b2a20a1eabfb608b”}]
我们设置diffculty=2运行,结果如下:
获取示例
从GitHub下载:https://github.com/ecustjanny/PokerBlockChain
本章摘要
通过实际编码,你已经掌握了一个简单的区块链代码,学会了创建区块,并通过工作证明机制,让你的区块链接到主链上,还可以用来测试数据篡改的有效性
文章链接:https://www.btchangqing.cn/95426.html
更新时间:2020年12月02日
本站大部分内容均收集于网络,若内容若侵犯到您的权益,请联系我们,我们将第一时间处理。