首页 技术与阅读 生活 关于我

比特币的基本原理 -- 数十年来密码学、分布式系统和货币研究的巅峰之作

写在前面

参考资料列在了最后面,本文的内容基本都来自于这些参考资料。如果觉得看不懂,可以直接看这些参考资料,写得都蛮不错的。

目录

支付手段的演变

从古至今支付手段都是处于不断的发展和变化之中,大致上经历了以物易物、实物货币(黄金)、符号货币(人民币、美元等)、中央系统虚拟货币(银行、支付宝、微信支付等)、分布式系统虚拟货币几个阶段,其中比特币便是分布式系统虚拟货币的开山之作。一般来说,自我们人类存在以来,大致可以按照上古时代、农业时代、工业时代、信息时代来划分,其实当从货币支付角度来看的时候,每个时代都伴随着新的支付手段的产生,而比特币这种新型的分布式系统虚拟货币的诞生,是不是意味着下一个时代的诞生呢?

货币必须要具备一些基本的属性,比如要稀少、珍贵、便携,产生速度不易过快或过慢,最好是可控的,只有在具备了这些基本属性之后,才有可能被广泛的接收,使得货币在人类的各种交易中发挥其作用。

货币具备了一些基本属性之后,还必须得有手段保证其发行量、防伪、购买力。实物货币是靠天然的产量限制货币的发行量,靠天然的化学属性进行防伪,靠天然的珍稀性保证购买力;符号货币靠中央银行的领导和经济专家决定发行多少货币,靠不断的提高制作工艺和更高级的验钞机进行货币防伪,靠国家力量来保证购买力;中央系统虚拟货币靠中央银行的领导和经济专家决定发行多少货币,靠中央系统的总账本记录所有交易进行货币防伪,靠国家力量来保证购买力;分布式系统虚拟货币靠指定总量来决定发行多少货币,靠区块的产生速度来控制货币的发行速度,靠分布式系统的总账本(区块链)记录所有交易以及密码学来进行货币防伪,靠其天然的珍稀性保证购买力。比特币能否被广泛的接收,进而成为一种有效的分布式系统虚拟货币,还有待长期的观察和改进,不过它绝对是一次伟大而重要的尝试。

比特币的基本原理

概述

中本聪在2008年发表论文"A peer-to-peer electronic cash system",标志着比特币的诞生,没过多久中本聪又编写了bitcoin core(比特币核心),产生了第一个区块和第一笔交易。中本聪在第一个交易中,写下了"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks(2009年1月3日,财政大臣正站在第二轮救助银行业的边缘)",一方面标志着比特币在这一天正式开始运行,另一方面讽刺了当前货币制度的不合理性。在发表了论文和编写了比特币核心,并使系统稳定运行了一段时间后,中本聪逐渐淡出公众视野,到现在也不知道中本聪真名叫什么,到底是谁。

货币的一切都是在保证交易的正常进行,在中央系统虚拟货币中,我们之所以可以正常的进行交易,是因为我们在中央系统有一个账号及对应的密码,另外中央系统中会记录每个账号所有的交易信息。在一定程度上来说,比特币也类似于中央系统虚拟货币,只是比特币是把所有的交易记录在区块链中,而区块链又是完全公开的,只要满足一定的条件谁都可以在区块链中记录下交易。

总结起来,比特币需要解决的就是两个问题:比特币的所有权问题和比特币的双重支付问题。在交易中来分析,比特币的所有权问题就是在交易的时候有没有足够的比特币以及使用的比特币确实是属于你的,比特币的双重支付问题就是要保证已经使用过的比特币不会再被使用。我们要明白一点,比特币并不是一张纸或是某个具体的数字,一个人拥有多少比特币是根据你在总账本(区块链)中的交易记录来查询的,其实在中央系统虚拟货币中也应该是这么做的。

再来分析一下,比特币的两个问题在中央系统虚拟货币中是怎么解决的。所有权问题,因为我们在中央系统中有账号和密码,所以只要用户提供的账户和密码是对应的,那么该用户就可以使用此账户中的货币,而中央系统还可以根据用户提供的账号查询出该账号的所有交易信息,再根据这些交易信息计算出一些统计信息,这些统计信息中就包括该账号的余额,当进行一笔交易时,只要余额足够就可以成功交易。双重支付问题在中央系统虚拟货币中是不存在的,因为中央系统的账本只有中央系统可以书写。

在分布式系统中账本(区块链,记录了所有的交易信息)是完全公开的,这个特性引起了上述两个问题,而比特币以创造性的方法成功的解决了这两个问题。完全公开的账本(区块链)也带来了很多好处,比如我们的交易不再依赖某个中央系统,谁都可以进行审计等等。

数字货币的研究由来已久,所以所有权问题并不是中本聪在论文中主要考虑的问题,该论文的最大的创新之处,在于完美的解决了双重支付问题。

总账本,即区块链

我们可以把区块链理解为一个数据结构,而比特币是使用该数据结构实现中央系统虚拟货币的一个算法。

交易是指某个比特币地址向另一个比特币地址支付了某数量的比特币;区块是指包含区块头和多个交易信息的一个结构体;区块链是指区块链接而成的一个链表。我们可以把区块链理解为一个链表,这个链表中的每个节点是一个区块,区块中又包含了一定数量的交易信息。

区块的产生速度是在算法中通过调整难度来控制的,基本上是每十分钟产生一个有效区块,该区块中包含了这段时间或更早时间的一些交易信息,每两个星期会根据区块产生的速度来调整难度,以保证每十分钟产生一个有效区块的目标。我们可以在网站Blockchain info上来查询区块链中的信息,如某个交易的信息,某个区块的信息,某个比特币地址的所有交易,当前的区块链长度等等,可以看到区块链确确实实是完全公开的。

产生交易

如果我们不想到网站上去查询信息、或是要发起一笔交易、或是要接收比特币等,都需要在本地安装软件,最好最全最权威的应该就是比特币核心。

在windows下安装比特币核心,可以到到比特币的官方网站http://bitcoin.org上下载,如下图:

bitcoin core windows

下载完了,即可双击进行安装,这和安装普通的软件没什么区别,安装完成要经历一个同步区块链的过程,区块链的同步过程根据网速的不同,时间可能会需要好几天。同步完成后,就可以正常的使用比特币核心了,如下图。比特币核心的使用大概就是加密钱包,备份钱包,接收比特币,支付比特币,终端的使用等。钱包记录了你所有的私钥,可以用来接收/支付比特币,很多的比特币软件和基本所有的手机比特币应用都只有钱包功能。通过终端提供的很多命令,我们可以查询到更多的信息,实现更多的功能。

bitcoin core windows

在centos 7(linux类)下安装比特币核心大致要使用到下面几个命令,很多linux下的程序都是通过这种方式来安装的(即所谓的源码安装):

git clone https://github.com/bitcoin/bitcoin.git
必备库安装(参考文档./bitcoin/doc/build-unix.md)
./autogen.sh
./configure
make
make install 

安装完成后使用以下命令来启动比特币核心:

bitcoind -txindex --daemon  

启动完成后,也需要同步区块链,可以通过以下命令来查询同步的过程,bitcoin-cli是比特币核心的客户端,可以实现比特币核心提供的所有功能。

bitcoin-cli getinfo

可以通过以下命令来查询bitcoin-cli提供了哪些功能:

bitcoin-cli help

下图使用bitcoin-cli获取第21个区块(创世区块编号为0)的信息。

get block info

下图使用bitcoin-cli来获取第21个区块中唯一的一条交易的信息。

get raw transaction

下图是交易这个结构中包含的具体字段,对于理解比特币的基本原理来说,最重要的是vin和vout;vin是交易的输入,也就是用于当前交易的比特币来自于哪里,vout是交易的输出,也就是当前交易的比特币支付多少给谁;一个交易可以有多个vin,多个vout。

transaction

我们可以用现实生活中的一个例子来理解这个问题,比如我们平时买东西,若需要支付给商家8元钱,那我们会在钱包里面找到两个5元(vin),两个5元共10元,其中8元用来支付给商家(vout),另外2元会支付给自己(vout)。在现实生活中,我们是把10元先给商家,商家再把2元通过找零的方式退还给我们,但其实这个过程也可以理解为我们是把8元给了商家,把2元给了自己,因为在比特币中不存在找零的过程,所以实现起来的时候就是一部分给商家,一部分给自己。那为什么不给商家数量正好的比特币呢?因为我们这里的vin实际上是前面某个交易的vout,就像我们钱包里的那两个5元钱如果追根溯源也都是来自于前面某次交易别人给我们的,而前面某个交易的vout中有多少比特币的数量是一定的,有的时候一个vout不够支付,我们需要把前面好几个交易的vout组合起来支付,也就像这里我们需要用两个5元来组合为10元一样。

在上面交易的数据结构中,我们可以看到vin中有txid,vout这两个字段,它们就指明了当前交易的比特币来源,即txid中编号为vout的比特币。这里一定要理解区块链中记录的信息就是交易信息,而我们用于当前交易的比特币实际上是来自前面某个交易的收入,那这样追根溯源之后我们会发现这些比特币最终都是来自于某区块的coinbase交易,coinbase交易就是矿工生成了一个有效区块后,在区块中加入的一条支付给自己的交易,这是矿工挖矿的收益来源之一(另一来源是交易费,每笔交易都会收取少许的交易费),也是目前矿工挖矿最主要的收益来源,coinbase交易也是产生比特币的唯一方式。矿工挖矿生成有效区块,在其中加入coinbase交易,最初coinbase交易中支付给矿工自己的数量为50个比特币,以后是大概每4年减半,因为区块的生成速度(每10分钟一个),每个区块产生的比特币(coinbase交易)都是可控制的,所以最终会产生多少个比特币,在什么时候产生最后的比特币都是可以预测的。

我们理解了交易中的vin是前面某一个交易的vout后,我们可以来定义一个概念,即UTXO(Unspent Transaction Output),也就是未支付的vout,下图中展示了UTXO。如果你能让别人相信你拥有该vout,那你就可以使用该vout来发起一笔交易。一个交易的生成首先要指定vin和vout,然后再使用私钥对此交易进行签名,这两步在比特币核心中都需要相应的命令来执行。

Unspent Transaction Output

到这里,我们可以重新来理解一下比特币的所有权问题,所谓的所有权问题也就是能够证明你拥有某个UTXO的问题。那这是怎么来证明的呢?就需要使用到vin和vout中的其它字段,也就是vin中的scriptSig字段,以及vin中指明的前面某个交易的vout中的scriptPubKey。注意这里是指vin中指明的前面某个交易的vout,和当前交易的vout没有关系,当前交易的vout会成为别的交易的vin,但是和当前交易vin中指明的vout没有任何关系。

收集交易,产生区块

比特币使用的是p2p网络,一个节点可以和多个节点相连接,交换信息。当一个节点产生了一笔交易后,它会把该交易传给它所连接的其它节点,当其它节点收到这笔交易后,首先会验证这笔交易,如果验证通过就会转发该交易,如果验证失败就是丢弃该交易。

普通的节点不会把交易记录下来,但是矿工节点会把交易记录下来,当需要新产生一个区块时,它就会把还没有包含在任何一个区块中的交易,包含在自己要新产生的区块中。

区块的数据结构如下所示,其中重要的是hash,merkelroot,tx,nonce,nextblockhash,hash是指前一个区块的hash值,merkelroot是区块中的交易形成的merkle tree的根节点,nonce值是为了生成有效的nextblockhash而准备的,nextblockhash是下一个区块的hash值。nextblockhash是根据区块中的hash, merkleroot,nonce生成的,它必须要满足一定的条件,即前面多少个字符为0,hash算法是一定的,可以通过改变nonce值来达到这个目的,需要为0的字符越多难度也就越大,所谓的矿工挖矿也就是不断的调整nonce值,以生成满足条件的nextblockhash。

generator block

矿工收集交易信息,是为了自己的收益,矿工的收益来自于产生有效区块时,区块中的coinbase交易,coinbase交易包括系统的奖励和区块中交易的交易费。前面说到nextblockhas是通过hash算法计算hash,merkelroot,nonce而得到的,其中只有nonce可变,hash值是前面一个区块的nextblockhash,那merkleroot是怎么产生的呢?它为什么不可变呢?

merkelroot是交易组成的merkle tree的根节点,merkel tree的结构如下图。假如其中f1、 f2、 f3、 f4是4笔交易(奇数交易的时候,复制最后一条组成merkle tree),分别对f1、 f2、 f3、 f4求hash值得到h1、 h2、 h3、 h4,再对h1、h2求hash值得到h5,h3、h4求hash值得到h6,最后最h5、h6求hash值得到h7,那么h7也就是merkel tree的根节点了。merkle tree有一个重要特点,就是任何一个叶子节点的细微变化都会导致根节点的面目全非,反过来我们也可以说merkle root的根节点一样,那么它们的叶子节点也就一样。因此我们可以知道,只要区块中某个交易发生了细微变化,都会反映到merkleroot中。

merkle tree

确认交易,产生区块链

区块链是区块的链表,其结构如下面的示意图所示:

block chain

矿工的工作就是不断的收集交易,产生有效的区块,获取coinbase交易中的收益。矿工通过工作量证明机制(proof-of-work),也就是不断的调整当前区块的nonce值,使生成的nextblockhash满足难度要求,难度要求也就是指生成的hash值前面有多少个零,零越多难度越大。矿工越多,难度就会相应加大;矿工减少,难度就会相应减小;目标就是使得每隔10分钟产生一个有效区块,难度会每隔两周调整一次。

当矿工生成了一个有效区块后,马上会将该区块传递到其它矿工处,并开始生成下一个区块,收到区块的矿工会马上停下手中的工作,验证区块的有效性,一旦验证通过便也会马上开始生成下一个区块。下图是一个具有多种节点类型、网关及协议的扩展比特币网络。矿池是由多个矿工组成的,它们的结合是为了降低风险,然后按比例分得奖励。关于这幅图的详细讲解可以看《精通比特币》。 p2p network

下面我们来分析一下,全网是怎么样保持都在同一个主区块链上进行工作,使得区块链中的信息保持统一的。首先,如下图所示,假如现在网络中所有节点的区块链都处于区块P,并在此基础上开始生成下一个区块的工作。 main chain

如下图所示,当某个时候若有两个节点都生成了有效的区块,于是它们开始向网络中传播,红色部分和绿色部分表示它们开始向网络中传播自己收到的有效区块。 main chain

如下图所示,红色部分和绿色部分都在区块P的基础上收到了各自的下一个有效区块,即区块A和区块B,这个时候两个区块链都是同样长的,所以他们继续在各自的区块链上往下生成有效区块。 main chain

如下图所示,当某个时刻又有一个节点在区块B的基础上,又找到了有效的区块,并开始向网络中传播。 main chain

如下图所示,原来在区块A上工作的节点收到粉色的区块后,发现这个区块不是在区块A上工作的,但却更长,所以就会抛弃掉区块A这条链,而转到区块B这条链上来;原来在区块B上工作的节点收到粉色的区块后,发现这个区块就是在区块B上工作的,就会很高兴,知道有节点已经在自己的区块B上生成了一个有效区块,这个时候区块B上的交易也就是有了一次确认,一般有了六次确认后,就可以确认该交易成功了。 main chain

比特币的所有权问题

在理解比特币的基本原理过程中,对我个人来说最难的就是比特币的所有权问题,虽然这不是中本聪最大的创新所在,不过他提供了一个很巧妙的解决办法。

我们再来回顾一下交易的结构,如下图所示,一个交易有交易编号txid,及其编号的hash值hex,有多个vin和多个vout,vin是指当前交易的比特币来自于前面哪个交易的vout,在一个vin中,指定了前面某个交易的vout,以及签名信息;vout是指当前交易的支付对象。一个交易的生成首先要指定vin和vout,然后再使用私钥对此交易进行签名,这两步在比特币核心中都需要相应的命令来执行。

transaction

下面我们再说明一下私钥(private key)、公钥(public key)、比特币地址(bitcoin address)之间的关系。私钥可以通过椭圆相乘算法生成公钥,反之不可;公钥可以通过哈希函数生成比特币地址,反之不可;私钥加密的数据可以用公钥解密,公钥加密的数据也可以由私钥解密;一般数据传输都是公钥加密数据,然后传输, 接收后用私钥解密。 private key, public key and bitcoin address

前面已经说过,比特币的所有权问题就是能够证明你拥有某个UTXO(未支付的UTXO)的问题,再进一步说就是证明你拥有UTXO(未支付的vout)中比特币地址对应的私钥。

在中央系统虚拟货币中,是通过用户提供账号和对应的密码,然后中央系统根据记录在自己数据库中的信息做验证即可,但是在比特币中不能通过这样的方式来验证某个用户是否拥有某个比特币地址的私钥,在比特币中,任何节点之间都是互不信任的,也就是其它节点要在用户不提供私钥的情况下,验证该用户是不是拥有该私钥。

下面我们来看这是如何做到的,如下图所示,演示了Bob用Transaction 1中的某个vout、自己的私钥和当前交易的vout(即图中的TX2 Template,这部分与验证身份没有关系,可以忽略)来生成Transaction 2的过程。在Transaction 2中,直接包含Transaction 1的TXID和Output Index Number;在Transaction 2中,直接包含Bob提供的公钥,公钥其实虽然不能由比特币地址反推而来,其实它也是公开的,比如查询该比特币地址以前的交易就可以找到,但是在这里是Bob直接提供的;在Transaction 2中还需要包含由Bob的私钥加密的数据,这里需要加密的数据画的是PubKey Script,其实还包含其它的。

P2PKH

当Bob生成了交易Transaction 2后,就把此交易传到网络当中,让其它节点来验证,验证一个交易的有效性除了格式方面外,一个主要的验证内容就是Bob拥有Transaction 1中这个UTXO对应的比特币地址的私钥。满足两个条件说明Bob拥有该UTXO:

下图演示了验证的具体过程,由Tranaction 1提供的数据(Transaction 1中vout的scriptPubKey的asm)为下图中上面一个灰色方块,Bob提供的信息是下图中的另一个灰色方块,下面就需要验证前面提到的两个条件,这里是通过OP_DUP这样的一些操作来实现的。 P2PKH validation

总结一下,比特币的所有权问题就是要证明某用户拥有某个UTXO,那么该用户要提供两个信息,一是公钥以及私钥加密的数据。能够验证通过,就必须要保证用户提供的公钥可以解密私钥加密的数据;另外,还必须要保证用户提供的公钥和该UTXO的公钥hash值是一一对应的,不然用户提供自己的公钥,那它当然可以解密自己私钥加密的数据。

再提一下P2SH(Script Hash),我们前面讲的都是P2PKH(Public Key Hash),P2SH是2012年提出的一个比特币改进方案,那为什么需要这个改进?我们一般的交易都是默认我支付了货币,对方就会给我商品,但也存在很多需要担保的交易,这时候怎么办呢,P2SH就发挥作用了,它的具体原理不在本文的讨论范围之内,就不赘述了。

比特币的双重支付问题

比特币的双重支付问题,是指当某个用户使用了某个UTXO完成交易1,获取到商品后,又使用该UTXO去完成交易2,在完成交易2的时候用户必须要保证当前的区块链不包含有交易1的区块,所以就必须要在包含交易1的区块的前一个区块后再重新生成有效区块,并期望能够成为全网承认的主区块链,这个可以通过计算可知,当交易1的区块后有6个区块(6个确认)的时候,这是基本不可能做到的。

当某一个区块的交易信息改变的时候,merkelroot就会改变,由当前的nonce值生成的有效hash值,就会失效,这不仅导致需要重新生成当前区块,因为区块是通过区块的hash相互链接的,还会导致需要重新生成后面的区块。在落后的情况下,要想追的上,就必须要花费足够大的算力,这也是所谓的"51%攻击"(当然不是真的需要51%的算力才能达到),但如果某矿工拥有了这么大的算力的话,正常的采矿会获取到更大的收益,所以也就从动机上杜绝了这样的事情发生。

block chain

所以,越是大额的交易就越需要得到更多的确认,一般等到六个确认就基本可以确认交易成功了,当然小额的交易就完全没必要等,默认成功即可。

比特币的问题

理解完比特币的基本原理后,它的问题最直观的就是有可能会产生通货紧缩问题。比特币的总量为2100万,总量本来是很容易更改的,但是基本不可能更改,因为投入了大量资源的矿工不会同意。比特币有可能出现通货紧缩问题是很直观的,因为通货紧缩是指钱少于商品(通货膨胀是指钱多于商品),比特币的总量固定,而商品数量是会不断增加的,所以出现通货紧缩的概率是很大的,但不是一定的。

cumulative BTC in circulation

矿工目前的奖励,来自于系统奖励和交易费;随着系统奖励的越来越低,到最后会为0,矿工挖矿是会消耗很多成本的,为维持盈利,矿工会不会收取更高额的交易费。

花旗银行的一篇报告中写道“工作量证明会产生大量的能源成本,我们认为最终这些成本会产生大量的能源成本,我们认为最终这些成本将会转化为高交易费,由用户承担,这样就造成比特币的成本要比中心化网络更加昂贵。”,我觉得蛮有道理。

矿工所做的一件事儿就是通过hash算法调整nonce计算满足难度要求的hash值,这件事儿本身确实是毫无意义的,但是如果比特币是有意义的,那么矿工维持了比特币的正常运行,它干的事儿自然也就是有意义的。

目前矿工单独挖矿的情况已经很少了,都会加入到某个矿池中,组成更大的算力,平分矿池的奖励。矿池会把当前的难度降低一些,比如本来是要求前10个字符为0,矿池就会要求它的矿工提交前8个字符为0的结果即可,这样一方面是作为如何在矿工之间分配奖励的依据,另一方面因为矿工提交的是满足前8个字符为0的结果,那么在这些结果当中很有可能有满足前10个字符为0的情况。

目前的区块由大矿池挖出来的概率很大,下图是各个矿池产生有效区块的比例。

mining

矿池这种形式的出现就会出现一个问题,那就是矿池会成为新的中心,而使比特币的去中心化失去意义,这样的趋势感觉是越来越明显,有一种P2PPool的矿池协议就是针对这个问题的一个解决方案。

其它方面

在理解完了比特币的基本原理后,可以继续研究比特币的BIP(即比特币的改进方案),替代工作量证明机制的权益证明,以及智能合约。

比特币的支付对象为一个比特币地址(或脚本),智能合约是说可以把某种虚拟货币支付给一个程序(也就是智能合约),智能合约的代表应该是以太坊了。

下图是Slock.it利用DAO实现的Airbnb的功能,最近DAO事件闹得挺凶,说明以太坊还有很长的路要走。

DAO

这些币都是对比特币进行了简单的改进,比如换一种hash算法,调整货币总量和产生速度等。

交易平台是指比特币和别的货币交易的平台,比如可以用比特币换人民币,当然也可以用人民币买比特币。

我个人在BTCC上花了100元钱买了0.0229个比特币,具体的过程如下:

下图是在OKCoin上截的图,可以看到比特币、莱特币的价格。 Trade

下图是币看比特币的钱包界面。 bikan

未来货币的状态应该是实物、符号、中央系统虚拟货币和分布式系统货币并存,但是拥有各自的交易场景,而随着支付方式的多样化,将会刺激产生更多的交易,刺激更多的科技、金融创新。

Baas是指Blockchain-as-a-service,即区块链即服务,这是我自IAAS,PAAS,SAAS,CAAS之后听说的又一个云计算的概念,希望它能早日发挥作用。

参考资料

comments powered by Disqus

技术与阅读

生活

关于我