zoukankan      html  css  js  c++  java
  • 初窥比特币

    写这篇文章是为了让我的一位策划同事能够理解比特币、区块链这些概念。他并不是计算机相关专业的,因此我需要写的尽可能简单,这是个很大的挑战。

    另外,本人学识有限,若有问题望指出。

     

    什么是比特币?

    什么是货币?

    货币是用于衡量物体价值的东西。在进行交易的时候,我们并不是以物易物,而是将物品换算成等价的货币。交易的一方支付货币,另一方支付需求的物品。可以很好理解使用货币的好处,具体本文不作讨论。

    什么东西适合作为货币?

    早期,人们使用贵金属作为货币,贵金属的特定是稳定(适合保存)并且总量稀少(也可以理解为总量相对恒定)。总量恒定同时意味着价格较为稳定,这对货币来说十分重要。试想一下,如果使用铁块作为货币,那么随着炼铁工艺的提升和更多的铁矿资源被发现并开采,你我手中的货币就会迅速贬值。这当然是不可以接受的。

    然而,使用贵金属也是有缺点的,比如不便携带、不易被切分等。于是人们发明了纸质货币。纸质货币比较特殊,它是基于使用者对某一机构、国家的信任来发行的。使用者相信纸质货币是不会被随意增发的,因此接受这张特殊的纸来作为交易的货币。

    至此,相信已经看出传统纸质货币的问题了。问题的核心在于信任,当被信任的一方默默的增发货币时,你我口袋里的钱被悄无声息的拿走并转移到另一个人的手中,而我们对此却是束手无策。因此,比起人为的约定,我更愿意相信基于密码学原理工作的比特币。

    什么是比特币?

    比特币是一种去中心化的电子货币。去中心化解决了传统货币基于信任的问题,比特币并不是依赖于某个机构,而是依据一套数学原理来做到了数量恒定。当然比特币还有其它的优点,比如交易的匿名性。在进行交易时,大家能看到的仅是,账户A支付X比特币给账户B这种信息,并不知道账户A、B具体是谁。这是因为一个账户实际上就是一个公钥,只要创建一个公钥即可进行交易,不需要什么实名验证。

    密码学知识查缺补漏

    在介绍实现原理之前,需要先说一下需要用到的一些基础知识。

     

    非对称加密

    非对称加密是这样的,我手上持有两个密钥(两串数字),分别是公钥和私钥。公钥是公布出去并且大家都知道的,而私钥则是藏起来只有自己知道的。这两个密钥的特点是,使用公钥加密的密文必须通过私钥解密,对应的,使用私钥加密的密文也需要公钥解密。

     

    哈希

    一般我们使用哈希算法(hash)来验证数据的完整性。hash算法为给定的一个段数据生成一个摘要(指纹)。hash算法的特点是,哪怕数据只有一小部分被修改,生成后的摘要也是差别巨大。因此,通过对摘要做比较的,即可验证数据是否相等,是否被修改过。

    数字签名

    数字签名技术使用了上述提到的非对称加密和哈希算法。考虑以下这种情况,A想要向B支付X比特币,于是它在账单上写上类似于这样的东西:

    //from: A
    //to: B
    //how much: X

    写好这些信息后,A需要把这份账单发出去。于是问题就来了,B收到这份账单时,怎么能够获知这个账单是出自于A的,而不是其它某个人以A的名义伪造的一份呢?

    因此,我们需要一种方法能够证明,这份账单确实是A发出来的,并且在它被发出后没有其它人对这上面的内容作出任何修改。

    数字签名就是为了解决这种问题。具体流程如下:

    (1)A在生成账单时,先使用哈希算法H为账单生成一份摘要Da,再使用自己的私钥对摘要进行一次加密得到结果C。并将加密的结果C随着账单一起发给B。

    (2)B在收到账单时,使用同样的哈希算法H计算账单的摘要Db,然后再用A的公钥解密C得到了Da。

    由非对称加密算法可知,一份数据被A的私钥加密,仅可通过使用A的公钥解密。因此,B可以通过比较Da和Db的值是否相等,来验证对方是否拥有私钥,从而对这份账单进行验证。

    好了,需要用到的知识已经准备妥当了,接下来就是主线了:P

    交易去中心化

    想象一下,使用一般的电子货币交易是如何进行的:发起支付时,先从某个特定的数据库中查找对应账户的余额,余额足够则可进行交易,否则拒绝。但是比特币不能这么做,因为在比特币系统中不能存在一个权威的中心化数据库来存储交易数据。这是为了避免比特币网络的运行是依赖于某一个机构、组织、公司的。因此,比特币使用了一种特殊的方法来存储交易。

    首先,所有的交易数据都被公开。任何人都能获知比特币网络开始运行至今的所有交易记录。通过这份交易记录,就能够计算出任何账户的“余额”。

    解决了查询账户“余额”的问题后,接下来的问题就是,如何更新交易数据?如果任何人都有修改交易数据的能力,如何保证这个系统是安全的?如何保证一个账户的余额是正确的?

    这个问题的解决方法有点类似于以前应对垃圾邮件的做法。

     

    解决垃圾邮件的思路

    解决垃圾邮件的一个方法是这样的:

    (1)在发送一个电子邮件时,需要找到一个这样的随机数。把这个随机数添加到邮件内容后面,对修改后的邮件进行哈希,计算得出结果是以"0000"开头的。

    (2)收到邮件时,通过验证这个随机数是否符合要求,从而判断是否是垃圾邮件。

    这个方法是利用了垃圾邮件的特点:大量对邮箱扫描发送邮件。

    使用这种方法时,要找到这个随机数,只能一个个数的去尝试。但在验证时仅需要一次计算即可。因此找到这个随机数的难度远远大于验证。可以想象的是,随着要求的哈希计算的结果开头的0的个数增多,寻找这个随机数的难度也进一步变大。但是验证却是轻而易举的。

    当邮件附带的随机数被验证通过时,隐含的意思就是:这封邮件是耗费了发送方一定的CPU资源才发送过来的。因此邮件过滤程序认为它不是垃圾邮件。

    工作量证明

    上述解决垃圾邮件的方法,其实是要求邮件发送方为这封邮件给出一个工作量证明,提高发送邮件的成本。比特币使用相同的原理来防止交易数据被随便修改。

    具体来说,比特币使用区块链来存储交易数据。而区块链是这样的一种数据结构:

     

    注:图片取自于Bitcoin: A Peer-to-Peer Electronic Cash System

    我来解释一下。交易数据以区块链的结构组织,每一个区块(链的节点)大致可以理解为存储了以下的数据:

    (1)前一个节点的哈希。

    (2)当前节点的交易数据集合。

    (3)一个表示工作量证明的随机数。

    通过节点的工作量证明保证了,如果某人想要修改一个节点的数据,必须要耗费与其相当的工作量(为此修改计算一个新的工作量证明)。又因为节点之间是通过哈希值链接的,因此在修改过一个节点之后,不仅要为当前这个节点重新计算,还要为这之后的每一个节点都重新计算工作量证明。往区块链里打入新的节点是十分困难的,除非控制了全网51%的计算力,否则没有人能轻易的往区块链连续打入数个节点。

    交易的过程

    举个例子,账户A向账户B支付X比特币,则流程大致是这样的:

    (1)A先使用之前提及的数字签名等技术,为本次交易生成一份账单。这个账单记录了B的公钥、交易的金额X和一个签名脚本S(签名脚本具体是什么可以先不管)。

    (2)之后A将这个账单数据广播给网络上的时间戳服务器。

    (3)时间戳服务器收集最近一段时间内发生的交易账单,对收到的账单校验并排除掉非法的交易,最后尝试将这些账单打入区块链中。而将账单打入区块链的具体方法是,为账单集合和当前区块链中最新的节点的哈希值,计算工作量证明。当找到这个随机数之后,就公布这个新的区块链。其它时间戳服务器如果认同这个新的区块链就会选择跟随它,并在之后在这个新的区块链下工作。

    激励

    将账单打包打入区块链是有难度的,这需要耗费大量的CPU资源去计算工作量证明,并抢在其它人之前将其公布。如果有人赶在你之前公布出计算的结果,那你这一段时间的工作就相当于是白做了。没有人会愿意免费去做这件事,因此需要一些激励。而比特币系统的激励则是,规定了在成功计算到工作量证明后,允许获得一定数额的比特币。具体操作是这样的,时间戳服务器会把自己应得的那份钱,随着收集的账单一起打包打入区块链中。比特币也就是通过这种方式,从无到有的产生出来的。

    这一过程有点像淘金:工人们辛辛苦苦把黄金从地下挖出来,得到的黄金便是对自己辛勤工作的报酬。之后,淘金工人可以使用所得的黄金去市场上购买其它东西,于是黄金就开始在市场流通了。因此,时间戳服务器将交易打包进区块链这一行为又被称之为挖矿。

    参考资料:

    (1)Bitcoin Developer Guide

  • 相关阅读:
    Xmind8 Pro 破解教程(序列号|破解文件)
    火狐真机绕过selenium检测
    ubuntu20.04 更新国内源,亲测有效
    superset 安装记录(win10)
    anaconda 环境切换
    创建型模式-工厂方法 (python实现 与 java实现)
    python 使用抽象基类,实现(类似java)接口(继承抽象类的方法来实现具体类)
    python 基于元类的单例
    希尔排序(python实现)
    内存操作的几个函数
  • 原文地址:https://www.cnblogs.com/adinosaur/p/9094923.html
Copyright © 2011-2022 走看看