一些人惨淡离场,一些人冷静下来思考。十问比特币,给我们带了一些解答。

这两天的心情,估计就跟过年一样的感觉吧。

之前的那些日子,一些人惨淡离场,一些人冷静下来思考。

但是,无论如何,静下心来思考,永远是对的选择。一方面是,不可避免的价格决定信仰;另一方面是,区块链作为多种技术的组合,有太多概念可被偷换、炒作、混淆

所以,在这个特殊的时间里,鸵鸟区块链实验室,带着一些问题再来回溯下比特币的设计逻辑。中本聪的伟大之处在于,将一系列技术巧妙地组合在一起,用经济学原理解决了技术上无法解决的问题。任何单个的技术特性并不构成区块链的本质。

当对区块链进行不同角度的解读成为了常态,这使我特别想穿越时空,回到中本聪设计比特币的现场,探究他是如何思考的?背后的逻辑是什么?所以我尝试用这篇文章探讨中本聪是如何一步一步设计出一个“点对点的电子现金系统”,如何用逻辑串联起这些区块链所用到的核心技术


点对点网络、非对称加密签名,哈希函数,UTXO、智能合约、分布式账本、共识机制、区块链式结构等


其中,中本聪贡献了UTXO交易记账方式,并创新地用经济激励组合起这些技术。

接下来,我们开始用提出问题,解决问题的思路,组合这些技术。

问题一: 怎么理解电子现金和记账? 

既然我们要设计的是电子现金系统,我们先来探讨一下电子现金的概念。

如果给出以上一笔记账,我们想有哪些情况可以这样记账?

情境1、银行系统中,V神向本聪支付1元钱

应对这次交易,银行会在自己的账目上进行一次划转记账:

这笔记账本质上是债务的转移,本来银行欠V神1元,变成了银行欠本聪1元。也就是本聪有权利用这笔记账向银行兑现1元。

情境2、现实中,本聪问V神借1元钱

这时V神会打一张白条给本聪:

将来,本聪可以用这张白条,向V神索要欠款。

情境3、点对点网络中, V神向本聪发送1元电子现金

这时,V神其实发送的是条记账,记账中的1元如果所有人都认可,即所有人都愿意兑现,那么基于比特流的这笔账目就可以作为电子现金在网络中自由流通。

情境4、V神向本聪支付一元现金


这种情况是,实体现金完成了物理转移后的记账,但货币本质上也是这样一种账目,本聪拿着1元现金,最终要向社会去兑现这1元纸币的价值。

我们可以看到,虽然四种情境不同,却可以用相同的记账方式,而电子现金系统本质上,是在网络上用账本记录价值的转移,但网络的自由属性,又让价值的传输面临着必然风险

问题二:电子现金在单笔转账中可能产生哪些问题? 

为了方便分析,我们借用情景3“V神向本聪发送1元电子现金”,暂时先不管电子现金的发行问题

当我们用以下记账方式,在网络中收发电子现金,会有什么问题? 

1.我们并不知道发出或接收这笔交易的人是本聪或V神本人,即现实身份和网络身份无法真实对应

2.本聪或V神可以不承认这笔记账,谎称未发生交易;

3.本聪或V神篡改交易;

对应这三个问题的实质是:

1.身份(与交易对应)的真实性:确认交易的发起方和接收方。

2.交易的事实性:交易是否真的发生,不可伪造。

3.事实的不可篡改性:交易发生后无法篡改。

针对这些问题,我们寻找解决方案。

问题三:怎样解决交易的真实性?保证交易不可伪造、无法篡改? 

1、传统思路:中心化担保记账

我们常用的方式是用可信第三方担保,比如,V神和本聪叫好朋友BM来做担保:

记账格式(一式三份)

这种记账方式学术名词为“三式记账法”。基于BM的公信力,BM可以认证V神和本聪身份的真实性,双方交易的事实性,此后任何一方篡改交易都可以找到BM的记账副本实现仲裁。

但是,如果BM作恶呢?

问题四:如何防止仲裁者作恶?

针对如何防止仲裁者作恶这个问题,实际上我们是在思考,如何在一个网络中进行点对点自由支付,既能够不借助中间人,还能保证支付的安全

为了达到这种安全,我们首先引入一个技术:非对称加密签名

先简单解释一下数字签名生成和校验的过程

1 生成:用generateKeys方法把keysize输入,产生一对公钥和私钥

2 签名:将一段消息和私钥作为输入,输出签名消息

3 校验:将一段消息和签名消息和公钥三者输入,输出为真,则签名属实

我们用非对称加密签名可以解决两个问题:

1.公私钥即身份,解决身份问题,并有一定的匿名性,钱包地址即是公钥的哈希值;

2.用私钥对应的公钥可以校验交易的真实性。

我们用数字签名实现以下记账:

此支付中,本聪可以用V神的公钥校验支付,确认是V神支付并签名的,实现了:

1.真实性:只有私钥拥有者才能,对自己的支付进行签名。

2.事实性:公钥校验支付,证明支付已发生,并且没有私钥,无法伪造。

3.不可篡改性:没有私钥,不能修改已确认发生的交易。

那么又有一个新问题,如果是私钥拥有者篡改交易呢?

另一方面,以上支付仅在两人之间发生,实际是,支付发生在更大规模的网络中,网络中各节点如何确认,支付是否被本人篡改,确认账户中是否有足够余额?

问题五:在P2P网络中,随着节点和交易的增多,如何保证支付的有序性和不可篡改性?

假设在第一笔交易(交易1  “V神向本聪支付1元”)的基础上多加一些交易:

· 交易2  V神向本聪支付2元

· 交易3 本聪向v神支付1元

· 交易4 本聪向BM支付2元

首先,在P2P网络中,为了让每个节点,能验证全网的所有支付,每笔支付必须向全网广播,每个节点才能收到并记录下全网支付,进行判断。

当V神收到交易2和交易3时,因为是两个节点之间的有限交易,所以比较容易作出判断交易的有效性。

当引入第三个节,BM收到交易4时,作为新加入的节点,要重新验证之前所有的交易,判断本聪账户上是否有余额支付,所以需要对之前的交易进行检索和引用。而本聪在进行支付4中也需要提供证明,佐证自己的支付能力。

此时,为了已发生交易的不可篡改校验支付,我们再引入一个技术哈希指针

哈希函数简单解释,是任意长度输入经过哈希计算,能生成固定长度的输出

哈希函数有三个特性:

1.输入和输出有唯一的对应关系,两个输入即使差别很小,也得不到同一哈希值。

2.已知哈希值不能反向计算输入值。

3.哈希计算没有规律,要得出特定值或者特定域哈希值,只能不断随机尝试输入。

这些特性可以用来方便地链接两笔支付:

一方面,哈希指针指向的前一笔支付,可以很方便对前一笔交易内容计算哈希值,判断是否与本哈希值相等,确定前后关系

另一方面,前一笔交易有任何细微改动,都得无法算出相同的哈希值,保证了确认发生支付的不可篡改性

如下,用哈希指针将支付1、2、3、4连接成链,一方面可以确认所有支付的前后顺序,另一方面可以保证已发生的支付不可篡改

通过前三笔交易可知,本聪账上还有支付2中收到的2元,本聪可以在支付4用哈希指针直接引用支付2,即用V神支付给他的2元付给BM。

当BM收到这笔支付后:

1.可以通过哈希链条,确保之前的每一笔交易未被篡改过。

2.如果不放心,还可以用本聪和V神的公钥验证所有交易的真实性。

3.审计所有交易,确认本聪对支付2的引用有效无误的。

至此,我们用非对称加密技术、P2P网络广播哈希链式结构在有限节点系统中实现了:

1、非对称签名解决了去中间人的点对点支付,确保了支付对应唯一网络身份(即公私钥)的真实性,不可伪造性。

2、账本记录已发生的支付,可以按照前后顺序用哈希指针依次连接,保证不可篡改性,同时方便在账目中引用支付。

但是在现实中,我么面临的是更大规模的点对点支付需求,引发我们新的思考:

1.在支付规模极快增长后,我们应该选用什么样的记账才更高效进行交易的记录和审计校验。

2.已发生的交易因为哈希链式结构不可篡改,但当下发生的双重支付该如何避免?

例如:本聪在向BM支付2元后,又向第四个人发起支付5,用同一笔2元支付给第四人,而此时第四人有可能还未收到支付4的广播,甚至全网其它节点收到双重支付后也无法处理支付4和支付5。

问题六:在大规模、有并行支付需求的情况下,应该如何对交易记账?

对这个问题,我们通常会选择基于账户来记账,即对每一笔支付记录,一个账户支付到另一账户,并计算支付后账户的余额

例如,一开始本聪账户有3元,V神账户有0元,当本聪要支付给V神1元时:

1、检查本聪账户余额是否充足,如果不充足,就终止交易。

2、在本聪账户中减去1元,在V神账户中加上1元。

3、此时本聪账户有2元,V神账户有1元。

而中本聪并没有用这种记账方式,而是为比特币发明了UTXO方案,也是本文开头介绍的,中本聪运用的少有原创技术之一。

UTXO(Unspent Transaction Output未花费输出)是基于交易行为的记账方案。

先简单做个演示,假设系统奖励本聪3元,奖励V神0元,那么记账形式为:

由于是系统奖励,所以这笔支付的输入(put in)没有对应的前一笔输出(put out),只有输出V神0元,本聪3元。

我们接着用这种格式记录4笔支付:

分析一下交易1:

基于交易的记账,就要保障每笔交易的有来源(输入)有去向(输出),本交易1中的输入来源用哈希指针指向了“支付0”中的输出:本聪的3元。

而输出则指向V神和本聪的地址,UTXO的特点是,输入来源(即花费的输出)作为一个整体输入,全部消耗,而不是取部分输入,即在交易1中,输入的是本聪的3元,而后又向V神地址输出1元,反向本聪地址输出2元。

后面的三笔支付的思路一样,不再赘述。

所以我们说,某人有多少比特币,指的是此人地址中有多少UTXO(未花费输出),即我们可以理解为,在UTXO方案中,并没有我们通常意义上的币的概念,只有未花费的输出,一个人可以生成无数的公私钥对,拥有无数的地址,而这些地址中UTXO的总和需要钱包来管理,本文不对钱包做过多阐述。

UTXO方案在比特币中的代码表现为:

1、元数据:交易规模、输入数量、输出数量、本次交易哈希值、锁定时间。

2、输入:对应之前一笔交易的某个输出、之前交易的哈希值、前输出地址和签名。

3、输出:接收地址的公钥哈希值

这种结构中,比特币脚本代码自动处理签名校验支付校验等工作。对于比特币的脚本代码,其实便是智能合约的概念的源头。

在改进比特币的历史上,有过各种对脚本代码功能扩展的设想,即我们在一个点对点的电子现金系统中,能否通过自动执行的代码,来实现“满足某条件下必然执行的代码”和“点对点支付行为”的结合?

这就是后来的以太坊,本文暂不展开对只能合约进行阐述,有机会在后面的文章推演以太坊的逻辑。

至于为什么要用到UTXO方案,而不是基于账户的方案。我们还是回归到本节问题四,可能就是对应解决大规模的交易效率,和并行交易的问题。

1、如果我们用基于账户的方案,数据记录的对象是账户的状态,即每个账户对应的交易、和对应的余额。而如果基于交易来记账,对象则是UTXO,即UTXO对应的地址。

在一个电子现金系统中,公私钥虽然可实现部分匿名性,但是一旦一个地址和特定的人的行为对应上,匿名性便丧失了,所以大家更愿意用更多地址来进行支付交易,由此会产生大量的废账户,和冗余的数据。

而基于UTXO的方案可以一定意义上保证,每一条记录的有效性,而从数据库的层面上,UTXO方案相对而言更节省存储空间提高查询效率

2、如果,本聪支付给V神1元,和BM支付给本聪1元同时发生,基于账户的方案由于没有办法同时共享本聪账户的状态,所以没办法并行发生。而UTXO方案由于是基于每笔UTXO的状态,所以可以并行处理关于同一账户的多笔交易

关于UTXO方案,当然还有跟多的点可以深入,包括一些缺点和问题,但本文不展开讲,还是回归到设计的逻辑,我们毕竟是为一种电子现金系统设计数据库存储方案,我们对中本聪采用这种方案,偏向于理解为一个支付系统对效率的要求,同时也回答了本节探讨的支付系统大规模效率并行支付问题。

我们接着展开双重支付的问题。

问题七:如何解决双重支付的问题?

我们仔细思考双重支付问题的核心,其实是在大规模的点对点网络中,我们无法解决分布式账本一致性问题,当一个没有同步最新最准确账本的节点时,会受到双重支付攻击。

要解决这个问题的本质,是谁来记账的问题,是所有人都可以来记账;还是有限的可知节点记账(pbft、paxos);还是选举出一个可信的节点,来记录大家都认可的公共账本。所以虽然网络是分布式的,但是要解决双重支付的问题,我们还是选择用一本可靠的公共账本来解决。

因为在一个开放的,节点能随意进出的网络中:

1、无法让每个节点保持持续更新状态。

2、节点状态不可知,无法确认网络中节点是临时离线还是永久离线。

3、女巫攻击,及公私钥生成成本低,如果采用一人一票制,就会有大量低成本节点破坏共识过程。

所以,没有办法直接应用有限节点的投票百分比方式,只能选择一种机制进行竞争记账。

关于记账节点是有限的还是无限的,其实牵扯到区块链中常被大家提到的公有链、私有连、联盟链问题,和公有链竞争公共账本记账权的共识机制问题。

此处我们不展开探讨,我们还是专注于讨论,在一个节点完全自由进出,所有节点都有权利记账的分布式网络中,怎样设计一种公式机制进行竞争记账,通过可靠的分布式公共账本解决双重支付问题,达成分布式共识

提到分布式共识,其实回到了一个点对点的支付网络的本质,即分布式网络的问题

分布式网络有一个CAP定理:

分布式系统最多在一致性、可用性、分区容错性之中同时达成两者

由于作为一个交易系统,必须达到其中两者:

可用性:在一些节点故障或作恶的情况下,数据能否正常更新,即支付正常进行。

分区容错性:因为账本更新不同步,能否容忍产生错误分区(即区块链结构的分叉)。

其中,可用性必然要满足,分区错误必然发生,所以点对点的支付系统必然达不到高度一致性的要求。

至此,我们需要解决的是,在一个低一致性的网络中解决:

怎样避免女巫攻击。

怎样争夺记账权(分布式网络的公共账本),达成共识记账,避免双重支付。

问题八:如何解决女巫攻击的问题?

我们可以这样理解女巫攻击,发邮件由于成本非常低,所以我们经常收到垃圾邮件。

所以解决女巫攻击的核心是,使得攻击成本大于收益,避免大量低成本的恶意节点争夺记账权。此时我们引入工作量证明(POW)的概念。

我们选用哈希函数SHA256,来进行工作量证明。

此时我们回想哈希函数的第三个特性,如果给定下面的哈希函数:

“hash(给定信息+随机数)=特定域哈希值”

当对给定信息和随机数进行哈希运算,要得到特定值或者特定域值时,这个随机数只能用穷举法得到。

即工作量证明pow的特征:

1、寻找到特定域的哈希值对应的随机数很难。

2、用给定信息和随机值计算哈希值很简单。

下面列举一下一些哈希值,有个直观感受

(哈希值每位数字都可能是0123456789abcdef):

例:

6797aed6e76de66dcd7ad5fd3fd2d3f4d567

7f6cdc908f908ddae325da4e5acef5fe675ef5

000006e76de66dcd7ad5fd3fd2ae325da4e5

0000000000000000 dc908cd7ad5fd3fd2ad

一般哈希运算得到的哈希值类似前两个,但是当要求得到第三个,甚至第四个哈希值,需要进行大量的穷举运算,才能试出随机数。我们一般所说的比特币挖矿即为寻找随机数的过程。

再次总结一下POW的特点:

1、只能用穷举法寻找随机值。

2、所以寻找随机值的过程全凭运气。

3、难度可调:调整0的个数。

4、难度调整可按照一个标准进行:即工作量证明成本高于作恶收益

至此,我们用pow机制解决了女巫攻击问题,让争夺记账权的行为有了成本。

但同时会出现一个新问题:

如果成本大于收益,怎么激励节点去争夺记账?

例如:

有一笔1000元的转账,记账的工作量成本调整到1000元,这时候如果花费500元成本才能获得50%概率的记账权。对于这种记账,节点根本没有足够的动力,更不用说争夺记账。

问题九:怎样激励节点争夺记账权?

我们想到两种方式:

· 打包交易区块,对区块进行记账。

· 对记账者进行比特币奖励,和交易手续费奖励。

打包交易,使得每次包含的交易变多,收益变多,一定程度上缓解了激励问题,但是一般一个节点对一个区块中所有交易进行双重支付攻击不现实。

所以中本聪用奖励比特币的形式,让记账打包这个行为被重金奖励,使得节点有足够的激励去记账。

这正是比特币设计最巧妙的地方,在纯技术组合之上引入了经济激励

基于这种激励形式,虽然在技术上双重支付已被赋予极大的成本,但最终解决双重支付问题的方式是,让整个网络中的所有节点有了一致的利益

1、最开始,记账节点为了维护比特币网络,认真记账,避免每个区块中的双重支付和其它问题,使得比特币支付网络具备了支付功能和价值,而这样的点对点的支付网络所带来的价值又让比特币本身的拥有了价格,并且由于一定的金融属性,导致比特币有价格上涨金融基础。

2、这时节点矿工们拥有比特币和算力,如果比特币网络不可靠,手上持有的币和挖矿设备会失去价值,所以节点为了一致的利益共识和经济激励,会负责地为支付网络记账,甚至花更巨大成本继续争夺记账权。相应的,全网算力的提升又使得比特币网络可靠性更强。

3、工作量证明机制和比特币奖励机制的结合让网络所有节点拥有了共同的利益。所以从技术层面来看,工作量证明机制实现的是全网记账规则的共识;从经济层面上来看,对通过工作量证明争夺到记账权的节点们,又形成可牢不可破的利益共识,所以这两个层面的共识是相互成全的,缺一都达不到全网形成统一又可靠的账本

分析到这,我们对网络运行规则应该有了一个清晰的认识,他的运行原则如下:

1.允许任意节点自由进出网络,节点间进行点对点支付,广播交易。

2.同时节点可以参与竞争记账。

3.竞争节点进行穷举随机数,进行工作量证明竞争记账权。

4.试出随机数的记账节点打包交易,验证交易,生成有效区块,并广播全网。

5.其他节点收到广播验证:交易的有效性和区块的有效性。

6.节点验证区块后更新账本,并终止工作量证明工作,更新未确认交易池。

7.节点在验证的区块后面,寻找新的区块。

8.循环往复直到永远。

我们直观看一下区块链的结构:

针对这个区块链结构提几个重点:

1.链式结构其实有两层,一层是每笔交易指向前一笔交易,一层是打包交易的区块,与前一个区块一相连。我们要意识到一笔交易指向的前一笔交易不一定在区块链的前一个区块上。

2.Merkle根是,区块体中记录的交易用哈希指针一层一层指向一个Merkle根,由于区块头很小,区块体很大,而一个交易只对应一个Merkle根,所以在验证交易的时候,节点可以通过只下载区块头,寻找Merkle根的方式验证,提高验证效率。

3.在区块体的交易中,第一个是币基交易,记录着奖励比特币的数量和对应记账矿工的地址。币基交易即比特币的发行方式,比特币每10分钟打包一个区块,每个区块现在奖励12.5个比特币,每四年减半。

说到这,虽然为了共同的利益,矿工一般都选择认真记账,剔除双重支付和有问题的交易,但是还会有一个问题:

两个记账节点同时发现一个有效区块怎么处理?即分叉问题。

问题十:怎样处理区块链的分叉?

针对这个问题的答案,其实是不处理,区块链有自身的运行规则,区块链网络在运行过程中自然会有一条最长的链,而大家都以最长的链作为全网的有效公共账本:

1.不干预,按照交易规则和共识规则自动运行。

2.节点选择交易最合理,最长的区块链。

3.竞争可能持续多个区块,最后节点切换到更长的链条挖矿。

这种方式的特点:

1、当前区块并不能保证交易状态,由最长的链条决定

2、确认数越多,新链替代成本越高,交易越不可篡改。

所以一般我们会多等一些确认,才认为交易真的成功了,比如比特币的6次确认。

从本质上讲,最长链其实是最重的链,拥有算力最多的链,共识更牢不可破的链。

写在最后:

到这儿,我们已经完整地设计出了一个点对点的电子现金系统。

我们选用点对点的网络,希望构建出,能不通过第三方自由传输价值的网络

我们又用非对称签名解决了,点对点网络的身份问题、真实性问题和伪造交易的问题( 只有窃取私钥才能伪造交易);

在点对点网络中进行记账、数据存储时,我们用哈希函数构建了链式结构,使得我们的交易有序可追溯,已确认的账本难以篡改,哈希函数不仅链接了支付,更构建了区块链账本的基础架构,同时也是后面进行工作量证明的技术方案;

而在解决谁来记账,构建可靠的公共账本时,我们运用了工作量证明pow共识机制来进行争夺记账权,并创造性地和经济激励结合在一起,进一步解决了双重支付问题,同时使得整个网络有着牢不可破的利益共识。而这种最长链代表着有效记账的机制,又天然解决了区块链分叉问题

当然,分叉问题其实不需要解决,区块链的世界是个自由的世界,只要有一群节点愿意认同其它共识,或者新的技术来构建新的区块链条,完全可以硬分叉出一个新的社区,这也许就是区块链的魅力,它自由,它不惧节点的不一致性任意进出,我们用一整篇文章来对设计思路进行梳理,最后发现,其实共识才是区块链的灵魂

而这种共识,正好,也必须是基于利益的。因为,它符合人性;因为,它使共识具有广泛性。人类社会不缺乏协作,但是鲜有像比特币这样,达到如此广泛和大规模的共识,也许这就是区块链的意义,改变共识的方式,降低共识的成本,提高共识的效率,产生大规模协作的价值