区块链的过去与未来

谈到区块链就不得不提一下密码朋克(Cypherpunk):

  • Tim May是密码朋克(cypherpunk)组织的发起人,1992 年在他加州的家里,发起了密码朋克邮件列表组织。共同发起人包括 Eric Hughes 与 John Gilmore。
  • 列出这个伟大组织中最知名的几个名字:
    • Tim May,Eric Hughes 与 John Gilmore(邮件列表组织发起人),
    • Jim Bell,David Chaum (大卫乔姆),
    • Phil Zimmerman (PGP),
    • Julian Assange(阿桑奇,维基解密创始人),
    • Adam Back (亚当·拜克),
    • Wei-Dai (名字是中国的,不知道人是否华裔。他在圈子中地位尊崇)和 Hal Finney (哈尔芬尼),
    • Tim-Berners Lee 爵士 (万维网发明者),
    • John Perry Barlow (赛博自由主义政治活动家)和 Nick Szabo(尼克萨博,BitGold 发明人,智能合约的发明人)。
    • Facebook创始人:肖恩帕克
    • 比特币创始人:中本聪
  • 该邮件组成员相关的技术发明:
    • Adam Back 发明了Hashcash,使用了POW算法
    • Haber / Stornetta 提出时间戳方法保证数字文件安全的协议
    • 戴伟 发明了B-money,强调点对点交易和不可更改记录
    • 哈尔-芬尼 推出了 “加密现金”
    • 最后中本聪借鉴了该组成员所提出的许多技术,在2008年推出了比特币系统,并发表了白皮书《比特币:一个点对点的电子现金系统》

区块链:

  • 上文中也提到了中本聪也是得益于许多组内成员提出的技术才创造出了比特币,比特币在一定程度上可以说是多种技术融合的实现,在当时其体现出来的思想是超前的,所以到现在才开始受到广泛关注。把这些核心技术综合提炼出来就形成了区块链的概念,由于是多种技术的融合,所以区块链技术不仅仅能够做数字货币,还有其他许多的应用场景。这里简单提一下为什么叫做区块链:因为比特币里的数据是通过一个个的区块来存储的,然后通过hash值来把这些区块连接起来,这样就形成了一条由区块组成的链条,所以被称之为区块链。

区块链前景:

  • 应用场景
    • 资产:数字资产发行、支付(跨境支付)、交易、结算
    • 记账:股权交易、供应链金融、商业积分
    • 不可篡改:溯源、众筹、医疗证明、存在性证明
    • 点对点:共享经济、物联网
    • 隐私:匿名交易

比特币是什么

比特币是一种数字货币,先不谈什么是数字货币,我们先来了解下什么是货币:

  • 凯恩斯《货币论》中说,货币是可以承载价值的一般等价物

一般等价物可以是任何东西,我们可以看看历史中出现的货币代表:

  • 贵金属货币:铜币、金银,这类货币的价值在于其金属本身的价值
  • 信用货币:银票,其价值取决于钱庄的背书
  • 信用货币:法币,其价值取决于政府央行的背书

数字货币:

  • 一串数字,以数字的形式承载价值,其价值来自于货币的数学特性(持久性,可携带性,可互换性,稀缺性,可分割性和易识别性)而非依赖于物理特性(比如黄金和白银)或中央权力机构的信任(比如法定货币),并且可以很方便的在网络中进行全球性的交易。而其主要的核心价值还是在于信任以及流通性

数字货币的信任从何而来:

  • 财产只受自己控制,不存在任何的中心机构以及第三方的信用机构,你的财产只在你的手上
  • 无通货膨胀,不存在央行大量印钞的情况
  • 没有假钞,作假的交易无法得到网络中矿工的确认,无法得到确认的交易即无效
  • 流通性好,可以全球流通,并且是点对点的直接到账,没有任何的中间环节

比特币除了是数字货币外还是一个去中心化的记账系统:

  • 中心化的记账系统:将账本数据存储到一个数据中心里,或者说一个中心数据库里
  • 去中心化的记账系统:将账本数据存储到每一个人的电脑里,分布式的进行存储,每一个人的电脑里都会有这份账本数据

比特币原理

账本如何验证:

  • 如下图,有一个账本,这个账本分别存储在不同的电脑上:

区块链技术的核心概念

那么如果其中有一个人更改了自己电脑上的账本,那么不就会出现假数据了吗。这样情况该如何解决?

  • 解决方案1:
    • 一一核对账本记录
    • 少数服从多数
    • 但是效率相当的慢,该方案行不通
  • 解决方案2:
    • 使用hash进行验证
    • 哈希函数:Hash(原始信息)-> 摘要信息
    • hash特点:
      • 同样的原始信息用同一个hash函数总能得到相同的摘要信息
      • 原始信息任何微小的变化都会hash出面目全非的摘要信息
      • 从摘要信息无法逆向推算出原始信息

例如下图中,通过hash函数计算出了账本的hash值,然后利用hash的特性进行账本数据的比较验证,也就是只需要对比hash值即可,那么就要比对比整个账本数据高效得多。这就好比我们下载文件时,经常会通过MD5来验证文件是否已经损坏或者被修改了:
区块链技术的核心概念

那么计算出hash值并验证后,这些信息存储在什么地方呢?区块链中账本的hash值和区块序号以及时间戳都存放在区块链的头部分:
区块链技术的核心概念

假设现在第一个账本已经完成验证且成功记账了(存到区块了),如果这时候又来了一个账本,那么当计算这个新账本的hash时会加上上一个区块(账本)的hash一起进行计算。如下:
区块链技术的核心概念

可以看到,当出现第二个账本时,对该账本进行hash计算,会将上一个区块的hash也包含进去一起计算,最后得出来的才是这个新账本的hash。

因为在计算下一个区块的hash时必须包含上一个区块的hash一起来进行计算才能得出,所以才会说这些区块是通过hash串起来的。这样也就形成了区块链,每个区块都包含上一个区块的hash,如下:
区块链技术的核心概念

由于这种下一个区块永远包含上一个区块的hash的特性,那么在进行账本验证的时候,只需要验证最后一个区块即可,因为到区块链中最后一个区块的hash摘要里就是间接包含了前面所有区块的hash,也就是验证最后一个区块时就可以间接验证前面所有区块的正确性,这样就无需整条区块链都进行逐个验证。只需要验证最后一个区块,并且验证的只是hash值,所以在速度上还是很快的。


账户所有权问题:

银行系统:

  • 需要去银行开户,提供各种资料
  • 通过×××、照片、手机号、支付密码等信息确认账户的所有权

比特币系统:

  • 点对点交易,没有第三方机构
  • 在比特币系统中,账户就是一个地址,现在一般称为钱包地址。账户 == 地址
  • 交易时就是将比特币从一个地址转到另一个地址的过程,而且账本上是不保存任何个人信息的,只保存交易信息
  • 所以谁能使用地址进行交易,谁就拥有账户的所有权
  • 银行卡有密码,相对的比特币地址也有密码,不同的是这个密码是一个私钥,谁获得这个私钥谁就能使用这个地址进行交易。所以私钥要保管好,不能泄露出去。而且如果私钥泄露了,要及时重新开一个地址,将比特币转走。因为私钥与地址的关系不像是银行账户与密码的关系,私钥和地址都是不能够重置的,一旦泄露也就意味着这个地址已经报废了。

我们都知道银行账户与密码是没有紧密联系的,而私钥和地址则是有联系的,因为地址就是通过对私钥进行hash计算得出的,虽然私钥可以推导出地址,但是地址是无法推导出私钥的。银行账户则不是由密码计算出来的,所以私钥不像银行账户的密码那样能够随便重置的。唯一“重置”的办法就是新开一个地址。私有与地址的关系如下:

地址: 2A39CBa2390FDe
私钥: sdgHsdniNIhdsgaKIhkgnakgaihNKHIskdgal

Hash(Hash(fun(sdgHsdniNIhdsgaKIhkgnakgaihNKHIskdgal)))  -> 2A39CBa2390FDe
  • 比特币交易纪录看起来是这样的:
{
    "付款地址":"2A39CBa2390FDe"
    "收款地址":"AAC9CBa239aFcc"
    "金额":"0.2btc"
}

付款方需要拥有地址2A39CBa2390FDe的私钥才能进行支付,在不泄露私钥的前提下,如何证明我们拥有某个地址的所有权,也就是如何使用某个地址进行支付?这时候就需要用到非对称加密技术(对交易进行签名):

  • 首先对交易信息进行hash计算得到摘要信息
  • 然后用私钥对摘要信息进行签名,得到签名信息

签名过程大概是这样:
1.对交易进行hash, 得到一个摘要信息(Hash值)

hash('
    {"付款地址":"2A39CBa2390FDe",
    "收款地址":"AAC9CBa239aFcc",
    "金额":"0.2btc"
    }') -> 8aDB23CDEA6

2.用私钥对交易摘要进行签名(付款方在安全的环境下进行,以避免私钥泄密), 用代码表示大概是这样:

#参数1为交易摘要
#参数2为私钥
#返回签名信息
sign("8aDB23CDEA6", "J78sknJhidhLIqdngalket") -> "3cdferdadgadg"

签名完成之后,就会开始在全网节点中广播这笔交易,广播内容包括:

  • 交易的原始信息
  • 交易的签名信息
  • 拟人来说就是相当于在某个广场用喇叭喊了一句:我2A39CBa2390FDe支付了0.2btc到AAC9CBa239aFcc,签名信息是3cdferdadgadg,你们来确认一下吧

广播过程实际上是发信息到相连的其它节点,其它节点在验证通过后再转发到与之相连的节点。比如说A节点发起这笔交易的广播,并让网络中的其他节点进行验证。B节点与A节点相邻,所以先收到这个广播信息,然后又广播给相邻的C节点,C节点又广播给相邻的D节点,如此循环下去,直至广播到整个比特币网络。

在其他节点收到交易信息的广播后,就会进行验证,主要是验证该签名信息是否是付款方使用私钥对原始的交易信息进行签名产生的,以及验证支付方地址是否拥有足够的支付金额。验证过程实际是签名过程的逆运算,用代码表示大概过程是这样的:

#参数1为签名信息
#参数2为付款方地址
#返回交易摘要
verify("3cdferdadgadg", "2A39CBa2390FDe") -> "8aDB23CDEA6"

如果验证输出的信息和原始交易信息的hash一致,则验证通过,记录账本,用代码表示大概是这样:

if(verify("3cdferdadgadg", "2A39CBa2390FDe")
    == hash('{"付款地址":"2A39CBa2390FDe",
              "收款地址":"AAC9CBa239aFcc",
              "金额":"0.2btc"}')) :
    # 写入账本 
    # 广播
else:
   # donothing

回顾一下签名及验证:

### 签名 ###
#参数1为交易摘要
#参数2为私钥
#返回签名信息
sign("8aDB23CDEA6", "J78sknJhidhLIqdngalket") -> "3cdferdadgadg"

### 验证 ###
#参数1为签名信息
#参数2为付款方地址
#返回交易摘要
verify("3cdferdadgadg", "2A39CBa2390FDe") -> "8aDB23CDEA6"

可以看到签名是对交易的摘要信息以及私钥进行计算,得出签名信息。而验证则是通过对签名信息和付款方地址进行一个逆运算得出交易的摘要信息,能够成功逆运算得出交易的摘要信息就代表验证通过,继续广播。

整个的交易过程及运算都不包含用户的个人信息,保证了匿名、隐私。在安全性上,由于没有第三方机构或信用中心,所以不会有人能够冻结或减少你账户的金额。账户的所有权都在我们手上,只要私钥不泄露,就能够保证账户的安全性。

补充说明

上面为了更好的理解,我对一些信息进行了简化。

比特币系统使用了椭圆曲线签名算法,算法的私钥由32个字节随机数组成,通过私钥可以计算出公钥,公钥经过一序列哈希算法和编码算法得到比特币地址,地址也可以理解为公钥的摘要。


为什么要记账(挖矿):

记账工作:

  • 记账就是将交易记录、交易时间、交易序号进行一个Hash打包的过程
  • 这样的一个打包过程是需要消耗计算机的计算资源以及电力的
  • 既然要付出代价,为什么还会有节点进行记账呢?这就涉及到比特币系统中的奖励机制了,计算出该hash的节点能够获取一定数量的比特币作为奖励,这也就是所谓的挖矿

挖矿 - 工作量证明:

  • 我们都知道现在比特币很值钱,现在挖出一个区块就能够奖励12.5个比特币,而一个比特币价值几万,那么12.5个比特币就是几十万。所以就会导致很多人争先恐后的去挖矿,人一多起来那么这就可能会导致记账错误,所以比特币系统中有规则来防止记账错误:
    • 首先在一段时间内(通常是10分钟)只能有一个人可以记账成功
    • 并且需要通过解决密码学难题(即工作量证明)来竞争获得唯一记账权,而难题的难度和计算时间以及区块的产出时间是有联系的,所以比特币系统中有一个平衡算法来平衡每10分钟左右才会产出新区块
    • 当产出新区块进行记账完成之后,其他节点只能复制记账结果
    • 工作量证明,通过上一个区块的hash值和交集记录集以及随机数变量进行计算得出,并且计算出来的hash值根据平衡算法的规则需要以n个0开头,只有不停地计算出满足这个条件的hash值,才能获取唯一的记账权,用伪代码表示一下:
      Hash(上一个Hash值,交易记录集,随机数) = 0000aFD635BCD
  • 我们知道改变Hash的原始信息的任何一部分,Hash值也会随之不断的变化,因此在运算Hash时,不断的改变随机数的值,总可以找的一个随机数使的Hash的结果以若干个0开头,率先找到随机数的节点就获得此次记账的唯一记账权
  • 在进行工作量证明之前,记账节点会收集交集记录集,获取方式:

    • 收集广播中还没有被记录账本的交易
    • 然后验证交易的有效性
    • 接着添加一笔给自己地址转账的交易(挖矿奖励),目前是12.5个比特币
    • 最后谁先计算出符合规则的hash值,就能将这笔账记录到挖出来的区块中,这样就能获得了交集记录集中所记录的挖矿奖励

    工作量分析,我们简单分析下记账难度有多大,Hash值是由数字和大小写字母构成的字符串,每一位有62种可能性(可能为26个大写字母、26个小写字母,10个数字中任一个),假设任何一个字符出现的概率是均等的,那么第一位为0的概率是1/62(其他位出现什么字符先不管),理论上需要尝试62次Hash运算才会出现一次第一位为0的情况,如果前两2位为0,就得尝试62的平方次Hash运算,以n个0开头就需要尝试62的n次方次运算。我们结合当前实际区块#522302信息来看看:
    区块链技术的核心概念

注:数据来源于 https://blockchain.info

以上这是一个真实的区块,区块的序号为522302,而该区块工作量证明的hash值以20个0开头,理论上需要尝试62的20次方次,这个数是非常非常巨大的,我已经算不清楚了,应该是亿亿级别以上了。如此大的计算量需要投入大量的计算设备、电力等。可想而知这个计算量是惊人的,靠单台计算机是无法计算出来的,所以现在的矿工都是组成矿池进行挖矿(矿池里的矿工按算力百分比来分收益)。

验证

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

如果验证通过,则表明已经有节点成功计算出符合条件的hash,自己就不再竞争当前区块打包,而是选择接受这个区块,记录到自己的账本中,然后进行下一个区块的竞争。
网络中只有最快得出hash的区块,才会添加的账本中,其他的节点进行复制,这样就保证了整个账本的唯一性。

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


以谁的账本为准?(共识机制):

上一小节我们介绍了,完成工作量证明才能获取唯一记账权。但是当很多的矿工同时进行挖矿,就会出现两个节点同时完成工作量证明的情况,这种时候该使用谁的区块?这就涉及到比特币中的共识机制了:

  • 我们都知道比特币是无仲裁机构进行裁决的,每个挖出区块的矿工都会说用我的区块,没有一个第三方来裁决用谁的区块。而比特币中的共识机制就是用于解决这种问题的,共识机制就是大家都需要共同遵守的协议
  • 为什么要遵守协议?因为节点的工作量只有在其他节点认同后,才是被验证为有效的。如果不遵守协议就无法获得其他节点的认可,挖出的区块就无法加入区块链中,那么矿工也就获得不到收益,所以节点才会自发的去遵守协议
  • 那么以谁的账本为准?答案就是取最长的那条链,也就是节点只会认可累计工作量最大的区块链
  • 而且每个节点都是独立的,只会在最长的那条链上继续进行挖矿,延长最长的那条链

下面我们简单描述一下分叉的产生及解决,当不同的矿工同时挖出同一个区块时,就会产生区块链的分叉,如下:
区块链技术的核心概念

注:因为区块是保存上一个区块的hash,所以箭头是指向上一个区块的

如上图,在3457这个区块上,产生了分叉,在同一时间上分别出现了3458A和3458B两个区块。此时,分叉不会马上得到解决,而是3458A和3458B两个区块都会分别被广播到比特币网络中。比特币网络中的节点视网络的情况,会分别接收到3458A或3458B的广播,也可能同时接收到3458A和3458B的广播。只接收到3458A的节点,会基于3458A区块上进行挖矿,而只接收到3458B的节点,则会基于3458B区块上进行挖矿。如果同时接收到3458A和3458B的节点,会先判断哪个区块的工作量更大,然后就基于工作量最大的那个区块上进行挖矿,另一个区块则放在一个备用区块池里。因为网络是不确定的,万一最后是备用区块池里的那个区块是有效的,则会把那个区块替换回去。

我们以上提到了不同的节点只会在各自接收到的分叉区块上进行挖矿,这样不同的分叉链之间就会进行一个竞争,最后始终是有一个分叉区块链的区块产出慢了一步,这样另一个分叉的区块链会变得更长一些,那么最终所有节点就会以那条最长的链作为主链。这样分叉就得以解决了。说白了就是由于分叉出现的两条区块会进行竞争,最终总是能竞争出一个最长的区块链,那么网络中的节点就会以那条最长的区块链为准。例如,最终是3458B所在的链先产出下一个区块,成为了最长的区块链那么就会以3458B所在的链为准:
区块链技术的核心概念