qianqianjun / SimpleBlockChain

一个简单的区块链模型,学习区块链的笔记,使用python3 实现了区块链的基本原理。使用Flask 构建 peer to peer 网络。另外包含java版本的代码,java版本未完成。

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SimpleBlockChain

一个简单的区块链模型,学习区块链的笔记,使用python3 实现了区块链的基本原理。使用Flask 构建 peer to peer 网络

比特币简介:

  • 比特币是一种基于分布式网络的数字货币。比特币系统(广义的比特币)是用来构建这种数字货币的网络系统,是一个分布式的点对点网络系统。

  • 比特币底层的技术:点对点网络,时间戳,加密技术,工作量证明,共识机制不仅可以用于比特币系统,还可以用于其他领域,比特币底层技术的集合称为区块链技术,可见,区块链是一系列技术的集合。

  • 比特币不等于区块链,区块链开发也不等于就是炒币

  • 比特币又称为区块链1.0,是区块链的典型应用。

比特币运行原理

区块链记账方法

假设有一个账单交易记录如下:

账号 入账 出账 余额 备注说明
王炸 100 190 收到货款
张三 100 30 ……
李四 120 90 170 ……

记账时间为:2019-02-24 14:50:01

区块链在记账是会把账单信息(包含账单号、记账时间、交易记录)作为原始信息进行Hash, 得到一个Hash值,如:787635ACD, 用函数表示为:

Hash(序号0,记账时间交易记录)=787635ACD

比特币系统里约10分钟记一次账,即每个区块生成时间大概间隔10分钟

在记第2个账单的时候,会把上一个块的Hash值和当前的账单信息一起作为原始信息进行Hash,即:

Hash(上一个区块的Hash值,序号1,交易时间,交易记录)=456635BCD

这样第2个区块不仅包含了本账页信息,还间接的包含了第一个区块的信息。依次按照此方法继续记账,则最新的区块总是间接包含了所有之前的账页信息。

所有这些区块组合起来就形成了区块链,这样的区块链就构成了一个便于验证(只要验证最后一个区块的Hash值就相当于验证了整个账本),不可更改(任何一个交易信息的更改,会让所有之后的区块的Hash值发生变化,这样在验证时就无法通过)的总账本。

哈希函数补充知识

  • 简介

    哈希函数:Hash(原始信息) = 摘要信息,原始信息可以是任意的信息, hash之后会得到一个简短的摘要信息

  • 特点
    • 同样的原始信息用同一个哈希函数总能得到相同的摘要信息
    • 原始信息任何微小的变化都会哈希出面目全非的摘要信息
    • 从摘要信息无法逆向推算出原始信息
  • 举例:

    Hash(张三借给李四100万,利息1%,1年后还本息 …..) = AC4635D34DEF,账本上记录了AC4635D34DEF这样一条记录。

  • 哈希函数作用

    • 简化信息:哈希后的信息变短了。
    • 标识信息:可以使用AC4635D34DEF来标识原始信息,摘要信息也称为原始信息的id。
    • 隐匿信息:账本是AC4635D34DEF这样一条记录,原始信息被隐匿。
    • 验证信息:假如李四在还款时欺骗说,张三只借给李四10万,双方可以用AC4635D34DEF来验证原始信息

区块链工作量证明(挖矿原理)

比特币系统记账需要把交易记录,交易时间,账本序号,上一个块的哈希值等信息计算Hash并打包,需要消耗一定计算资源个存储资源,需要付出成本,所以为了让网络可以运行,需要有一定的奖励措施,当节点完成记账工作后系统会给一定的奖励,这个奖励就是比特币的发行过程,因此形象的将记账的过程称为挖矿

协调记账工作

既然记账工作会有收益,那就会有很多人来争相记账,但是这样会造成记账不一致的问题,所以引入了比特币工作量证明来解决这个问题,有如下规则

  • 一段时间内(大约是十分钟左右产生一个区块) 只有一个人可以记账成功

  • 节点之间通过解决密码学难题来竞争唯一的记账权

  • 其他没有货的记账权的节点直接复制记账节点的结果并验证就好

在进行工作量证明之前,记账节点会首先做好如下准备工作:

  • 收集广播中还没有被记录在账本中的原始交易信息

  • 检查交易是不是合法(例如一个地址不可以转比余额更大数量的比特币到其他地方)

  • 验证交易是否正确的签名

  • 验证通过的交易进行打包

  • 添加一个奖励交易给自己(比特币的发行)

如果节点争夺记账权成功的话,就可以得到相应数量的比特币

工作量证明

从记账方法中可知,每次记账的时候只需要计算一个Hash值就好,只要知道了上一个块的哈希值,待挖块的交易信息就可以很快的计算出哈希值,这样没有办法争夺记账权了,为了确保十分钟左右(这与密码学问题难度有关)只有一个区块产生,必须要提高记账的难度。

现在采取的措施是要求生成的哈希值前边有若干个连续的0,当前区块链系统中要求有18个0,在计算哈希的时候再加入一个随机数,使得哈希值满足要求,但是这个随机数是无法直接计算出来的,没有捷径可走,只能从0开始一个一个尝试,直到哈希值满足要求。率先找到满足要求的随机数的节点就获得了记账的权利

  • 难度分析:

    哈希值每一位有26个大写字母,26个小写字母,10个数字,一共有62个字符,按照每个字符出现的概率均等来计算,第一位是0的概率是1/62,18个0的概率就是18个1/62相乘,理论上需要计算62的18次方哈希才可以找出来,所以如果一个节点计算出来这个值,需要投入很大的电力和算力,现在计算出这个值太难,一般没有单独的矿工挖矿了,通过加入矿池,按照算力来分收益比较常见。

验证

在节点成功找到满足的Hash值之后,会马上对全网进行广播打包区块,网络的节点收到广播打包区块,会立刻对其进行验证。

如果验证通过,则表明已经有节点成功解迷,自己就不再竞争当前区块打包,而是选择接受这个区块,记录到自己的账本中,然后进行下一个区块的竞争猜谜。

网络中只有最快解谜的区块,才会添加的账本中,其他的节点进行复制,这样就保证了整个账本的唯一性。

假如节点有任何的作弊行为,都会导致网络的节点验证不通过,直接丢弃其打包的区块,这个区块就无法记录到总账本中,作弊的节点耗费的成本就白费了,因此在巨大的挖矿成本下,也使得矿工自觉自愿的遵守比特币系统的共识协议,也就确保了整个系统的安全。

共识机制

在挖矿过程中,人人都想要争夺记账权得到收益,为了确保收益的合法性,只有当一个节点的工作量证明被其他节点认同的时候才会验证通过,这个节点才会获得收益,也就是只有遵守协议才可以得到其他节点的认同,这样,促使了数以万计的节点都遵守一个简单的规则,那么这个规则就是一个共识,就是一个大家共同遵守的一个协议规范

在没有一个中心化服务器的状况下,所有节点如何达成一个共识呢?

实际上,比特币的共识机制由所有节点的4个独立的过程相互作用产生:

  • 每个节点(挖矿节点)依据标准对每个交易进行独立验证

  • 挖矿节点通过完成工作量证明,将交易记录独立打包进新区块

  • 每个节点独立的对新区块进行校验并组装进区块链

  • 每个节点对区块链进行独立的选择,在工作量证明机制下选择积累工作量最大的区块链就是权威的公共总账本

前三条在工作量证明和记账工作部分已经说过,对于第四条,累计工作量最大的区块链就是最长的一个区块链,一个节点和自己的邻居节点进行数据比对,如果数据不一致,则要进行冲突的解决,最终达到和邻居节点的链数据一致的结果,当然,节点的每一个邻居节点也会做同样的操作,最终达到网络上存储的账本一致

解决冲突可以分为以下几类:

  • 节点的链比邻居节点的链长:很好,这个节点不需要自己存储的链进行操作,只需要告诉邻居节点,哥们,你的链少东西呀,赶紧同步一下

  • 节点的链和邻居节点的链一样,啥都不用作,继续检查其他邻居节点

  • 节点比邻居节点的链短:检查邻居节点的链是不是合法的链(哈希值对不对,工作量证明对不对)链合法的话用就用邻居的链替换自己的链,否则不替换,并告诉邻居节点链错了

共识机制的第四条保证了链条的增长只在最长的链上进行。

About

一个简单的区块链模型,学习区块链的笔记,使用python3 实现了区块链的基本原理。使用Flask 构建 peer to peer 网络。另外包含java版本的代码,java版本未完成。


Languages

Language:Python 52.5%Language:Java 47.5%