前言

今天刚看完结城浩老师的《图解密码技术》这一本书。在最新版中,有一小节介绍了比特币。对其也蛮感兴趣的,于是总结一下。

说实话不知道应该放在计算机科学底下,还是安全底下。但是由于其用了单向散列函数和公钥密码算法。思前想后,还是觉得应该放在安全底下为好。

正文

1. 什么是比特币

比特币是一种虚拟货币,也叫密码学货币。其实现由一个自称中本哲史(中本聪)的不明身份的人所发表的一篇论文。其于2009年开始被实际运用,随后在世界各国中流行了起来,美国于2015年开设了第一家比特币交易所Coinbase。1比特币通常读作1 bitcoin或者1 BTC,其余的单位如下表。

比特币单位(缩写)
1bitcoin(BTC)
0.01bitcent(cBTC)
0.001millibitcoint(mBTC)
0.000001microbitcent(ucBTC)
0.00000001satoshi

2. P2P网络

比特币与实际法币不同,其没有中央银行。换句话说,其完全依赖于全世界所有比特币用户组成的P2P网络。也就是说,全世界所有比特币用户的计算机共同保存、验证和使用支撑比特币体系的所有必要信息。

与其说是一种货币,不如说比特币是一种基于P2P网络的支付结算系统。其实际操作是对两个地址之间价值转移的永久记录。具体的会在后方说明。

3. 地址

比特币交易是在比特币地址之间完成的。假设Alice要从Bob商店购买商品,并通过比特币支付,其流程如下:

  1. Bob生成公钥地址B
  2. Bob商店将地址B告知Alice
  3. Alice生成公钥地址A
  4. Alice从地址A向地址B付款

比特币中使用的地址是由公钥的散列值生成的。具体来说,将椭圆曲线DSA的公钥输入SHA-256和RIPEMD-160两个单向散列函数来求出散列值,为其附加一些信息后再通过Base58Check进行编码,转换成字符串。为了防止混淆,Base58Check编码中不使用数字零(0)、大写字母O、大写字母I和小写字母l。

PS:比特币公钥生成的地址都是以数字“1”开头的。

4. 钱包

用户可以再自己的计算机和智能手机上安装钱包应用程序,也可以通过提供钱包服务的网站来使用比特币。

用户通过钱包生成密钥对,并据此在互联网上进行交易。其中公钥用于接受比特币,而私钥用于支付比特币。私钥保存在钱包中,和一般的密钥对的管理方法一样,不能泄露给被人。

5. 区块链

那么说了这么多,比特币究竟是如何通过钱包交易的呢?首先最重要的概念就是区块链。

简单来说,区块链就是永久保存比特币全部交易记录的公共账簿。全世界使用比特币进行的所有交易都被记录在这一本公共账簿中。顾名思义,区块链就是将交易以区块为单位组织起来,并形成一条链。

具体的交易流程就类似,往区块链中添加一条“从Alice的地址A向Bob商店地址B支付1BTC”的记录。这样的记录会被记录为以下两条记录:

  1. 地址A所能够支付的比特币数量减少1BTC
  2. 地址B所能够支付的比特币数量增加1BTC

也就是说,比特币支付的本质是“将地址A中减少的金额增加到地址B中”,其实这也是几乎所有支付的本质。而区块链就充当了记录这一交易的张博,记录了比特币体系中所有的地址至今为止所有的交易。那么对于任何一个地址,我们都可以计算出当前它所拥有的比特币数量,也就是其支付能力

6. 区块的添加

比特币的付款是以交易为单位进行的,若干个交易会被合并为一个区块,并被添加到区块链中,当P2P网络确认区块的添加之后,相应的交易也就完成了。一个区块是由若干条交易以及一个区块头组成的。一个区块头中包含着:

  1. 对他前面一个区块头的的散列值进行单向散列函数计算的散列值
  2. 本区块所有交易的整体散列值
  3. 除此之外,还保存着一个名为nonce的任意数值
  4. 以及时间戳等相应信息

由此可见随意篡改区块链的数据是很难的,因为需要改动该区块之后所有的区块数据。

7. 交易

我们下面来看一下区块中记录的交易数据是怎么样的。所谓交易,其实就是对“从一个地址向另一个地址转移了多少比特币”这一行为的记录。假设Alice从Bob商店购买了商品,需要向Bob商店支付1BTC的比特币。其实际行为如下:

  1. Bob商店创建公钥密钥对(公钥B和私钥b)
  2. Bob商店根据公钥B生成地址B,并发送给Alice
  3. Alicec创建公钥密钥对(公钥A和私钥a)
  4. Alice创建交易:“从地址A向地址B发送1BTC。”此时,Alice使用私钥a对交易签署数字签名
  5. Alice将这条信息发送至P2P网络,即向全世界广播这一条消息
  6. 随后Alice创建的交易与其他一些交易一起被合并成为一个区块,并添加到了区块链中
  7. 添加的区块被P2P网络确认后,“从地址A向地址B发送1BTC”的交易就成立了

对于全世界的人而言,谁也不知道地址A和地址B是谁的。如果Alice和Bob没有互相确认身份的话,甚至连他们也不知道。然而对于区块链这一个公共账簿来说,当交易确认的那一刻,地址A能够支付的金额就少了1BTC,而地址B能够支付的金额就多了1BTC,这与现实中的转账操作其实具有相同的意义。

8. 挖矿

到此为止,我们已经了解了比特币是如何进行交易的(从一个地址向另一个地址转一定数额的比特币)。但是交易前提是一方必须拥有一定数量的比特币,那么比特币最开始都从哪里来呢?

随着全世界的比特币交易不断增加,区块链也会随之不断增长,这就意味着P2P网络中存在着“某些人”在负责将新的区块添加到区块链之中。有意思的是,“将新的区块添加到区块链”这一行为,就正好相当于“创造新的比特币余额”。所以像区块链中添加区块就好像从金矿中挖出比特币意义,称之为挖矿,而从之这一挖矿行为的人被称之为矿工

由于区块链是一条单链,因此在某个特定的时间点只能向其中添加一个区块。按照比特币协议的规定,成功将区块添加到区块链的矿工将获得挖矿奖励以及该区块所有交易的手续费。同时,为了防止比特币被伪造,矿工必须证明自己确实完成了规定量的工作,这种证明被称为工作量证明,其必须通过散列值来实现。

要向区块链添加新的区块,矿工必须要生成合法的区块头,而且区块头中“前一区块的散列值”的格式是有规定的,它的若干个比特必须为0,如前一个区块的散列值可能为0000000000000000000000007780B6F7817C...

因此,区块头中之所有需要一个nonce的随机值,就是为了凑出像上面这样前面若干个比特都是0的散列值,也就是说,矿工需要不断更换nonce进行尝试,直到计算出符合要求的散列值为止。(散列值的单向性?暴力破解?)

这个过程实际上和暴力破解单向散列函数十分相似。当然,这只是为了证明某个矿工确实投入了大量的计算资源来完成工作,而不是真的为了去攻击单向散列函数。比特币系统中大约每10分钟会添加一个新的区块,为了保持这样的恒定速率,计算的难度(即所需0的个数)会不断地被调整。也就是说比特币的算力要求会随着时间推移持续增加,但是由于计算机的性能也会不断增加,希望两者将会与支持平(笔者的观点)。

9. 确认

由于全世界有大量的矿工在不断尝试添加新的区块,因此如果在某个时间点上有多个矿工同时计算出了符合要求的散列值,区块链就会因此产生分支。但是又由于比特币是一个P2P网络,无法确定到底是哪一个区块先到达了节点,比如节点1可能先收到区块A而节点2可能先收到了区块B,这样就会造成节点1和2的差异。那么到底哪个区块才应该被添加到区块链中呢?这个时候,P2P网络需要对此做出判断,这个动作称之为确认。当产生分支时,P2P网络的各个节点会选择计算量大的分支继续工作,从而抑制区块链继续产生分支。(但是两个区块都会被添加到区块链当中吗?)因为比特币系统假设善意的矿工所拥有的计算资源要大于恶意的矿工所拥有的计算资源,这也是比特币系统得以正常运作的前提。

10. 匿名性

我们可能经常听说“比特币交易是匿名的”,对于这里的“匿名”,我们必须正确理解。诚然,对于比特币而言,由于我们交易只需要地址,不需要任何其他的个人信息与之关联,这当然是匿名的。

同时,我们的交易会被公开给全世界的用户,并且交易记录也会近似永远地留在区块链上,所以用户通常都不会使用一个地址反复交易。

但是我们交易的对象一般不是匿名的,他们需要知道我们的地址,我们的一些个人信息,不然无法把商品交付在我们手中(至少也会和我们的联络人进行联络,当然其中你可以做一些增加匿名信的措施),因此只要你的对象宣布“这个地址是Alice的”,那么使用这个地址的所有交易信息都会公开。而且P2P网络性质就决定了某条交易所对应的节点IP是需要被记录的,这就产生了一定的风险。

比如说,在Blockchain.info网站上就可以查询区块链的所有数据,任何人都可以查询任何地址相关的所有交易信息。

将来比特币也许会改进这些匿名性相关的问题。(作者说的)

总结

就和本文说的一样,简单介绍一下比特币的历史、交易过程和其特点。这里的总结我们将会用作者的总结,更加的完整与完善,并且加上我们的补充。

  1. 比特币是一种基于P2P网络的支付结算系统,再通过公钥的散列值生成的地址之间进行交易
  2. 公钥用于接受比特币,私钥用于支付比特币
  3. 转账的合法性通过发送者用私钥进行数字签名来证明
  4. 所有的交易记录都近似永久地保存在区块链(公共账簿)中,任何人都可以对其其中的记录进行验证(透明性)
  5. 通过单向散列函数使得区块链的篡改变得非常困难,而且区块链之间的联系也让其篡改变得非常困难
  6. 通过工作量证明放置伪造,通过确认来防止区块链产生多余的分支
  7. 为了添加新区块,矿工需要计算出前面若干个0的符合条件的散列值(挖矿)。如果两个相同的矿工在同一时间点计算了相同的区块,那么计算量大的矿工的区块将会被延续。计算量小的矿工的区块就会被抑制不被产生任何新的分支,这一过程称之为确认

Q.E.D.


立志做一个有趣的碳水化合物