比特币协议实际上是如何工作的

导读:很多人都听说过比特币,也有不少人投资过比特币,但你真的了解比特币背后的原理吗?它如何是设计的?如何对抗双花?什么是工作量证明?作者MichaelNielsen 给我们带来了详尽的解释,本文来源于michaelnielsen.org,由蓝狐笔记社群“iGreenMind翻译”。

专门解释比特币的文章已经数不胜数,说它是一种点对点的网络数字货币。大部分文章都对加密协议做了很多描述,但还是省略了很多细节。即使是那些深入钻研的文章也常常忽略了关键点。

我写这篇文章的目的,是想用一种清晰、容易理解的方式来解释比特币协议背后的主要思想。我们将从最初的原则开始,建立起对比特币协议如何工作的宏观理解,然后深入到细节,从比特币交易中检视原始数据。

以详细方式理解比特币协议是一项艰巨的工作。相反,人们很容易把比特币看作是既定事物,对如何通过比特币致富更感兴趣,还有比特币是否是个泡沫,比特币是否有朝一日可能意味着税收的终结等等,这些问题都很有趣,但也严重限制了你的理解。

了解比特币协议的细节让我们有机会欣赏到其他方式无法触及的风景。特别是,它是我们理解比特币内置脚本语言的基础,这让使用比特币创造新型金融工具(如智能合约)成为可能。反过来,新型金融工具可以被用来创造新的市场,并促使新的集体行为成为现实。挺有趣的哈!

这篇文章的重点是解释比特币协议的细节。要理解这篇文章,您需要熟悉公钥加密,以及与数字签名相关的概念,我会假设你对哈希概念有所了解。这一切都不算困难。这些基本概念可以在大学新生的数学或计算机科学课上获取到。这些想法都很迷人,如果你对它们不熟悉,我建议你花几个小时去熟悉一下。

比特币的基础是密码学,这似乎令人惊讶。比特币不是一种货币吗?比特币不是一种发送秘密信息的方式吗?事实上,比特币需要解决的问题主要是确保交易的安全——确保人们不能相互窃取、彼此冒充等。

在原子世界中,我们通过锁、保险箱、签名和银行金库等设备来实现安全。在比特世界里,我们用密码学来实现这种安全。这就是为什么比特币在本质上是一种加密协议。

在这篇文章中,为了让大家容易理解,我的策略是逐步构建比特币概念。首先,我会解释一种非常简单的数字货币,它基于显而易见的想法,我们称之Infocoin,以区别于比特币。

当然,我们的第一个版本的Infocoin会有很多缺陷,因此我们将经历几次Infocoin的迭代,每次迭代都只介绍一两个简单的新想法。经过多次这样的迭代,我们将实现完整的比特币协议。我们会重构比特币!

这个策略比我一次性解释整个比特币协议要慢。但是,尽管你可以通过这种一次性的解释来理解比特币的机制,但很难理解为什么比特币的设计方式是这样的。较慢的迭代解释的优点是,它让我们对比特币的每个元素都有了更清晰的理解。

最后,我要提一下,我是比特币协议学习者里的新手(译注:对于世界上的绝大多数人来说,已经是老手了)。自2011年以来,我一直在跟进它(包括自上世纪90年代末以来的加密货币),但直到2013年早些时候才开始认真研究比特币协议的细节。我会感谢任何人对我的误解的纠正。在这篇文章中,我还提到了一些“作者的问题”——在写作中我自己曾经思考的问题。你可能会发现这些有趣的东西,但你也可以完全跳过它们,可别舍本逐末哦。

第一步:名意向

那么,我们如何设计一种数字货币呢?

从表面上看,数字货币听上去是不可能的。假设有个人(我们叫她Alice),她有一些想要花的数字货币。如果Alice可以用一串比特数字作为货币,我们怎么能防止她反复使用相同的比特字符串,从而产生无限量的货币供应呢?

或者,如果我们能以某种方式解决这个问题,我们怎么能阻止其他人伪造这样一串比特字符,并利用它从Alice那里窃取这些数字货币呢?为了把信息当作货币使用,这些是克服的众多问题中的两个。

(注:这也是为什么区块链第一次实现了不用中介掺合即可实现价值转移的原因,互联网的文章可以复制粘贴,比如蓝狐笔记的文章经常被人复制粘贴,并且修改文章,不标注来源。但比特币你可无法复制粘贴,无法花两次三次。)

作为Infocoin的第一个版本,让我们找到一种方法,让Alice可以使用一串比特字符作为一种新形式的货币(非常原始和不完整的),这样至少可以保护她免受伪造。

假设Alice想给一个叫Bob人一个infocoin。为了做到这一点,Alice写下了“我,Alice,给Bob一个infocoin”的信息。然后,她使用一个私人加密密钥对消息进行数字签名,并向全世界公布已签名的比特字符串。

(顺便说一下,我使用的是大写的“Infocoin”,来表示协议和一般概念,小写的“infocoin”指的是货币的特定面值。在比特币世界里,类似的使用是常见的,虽然不是普遍的)

这并不是一个令人印象深刻的数字货币原型,但它确实有一些优点。世界上任何一个人(包括Bob)都可以使用Alice的公钥来验证Alice是否真的是签署了“我,Alice,给Bob一个infocoin”这句话的人。没有人能创造出那个比特字符串(译注:这里可以理解为公钥签名),所以Alice不能转过身说“不,我不是想给Bob一个infocoin”。

所以协议规定Alice想要给Bob一个infocoin。同样的事实是——没有人能写出这样一个签名的信息——也给了Alice一些有限的防伪造的保护。当然,在Alice发表了她的信息之后,其他人可能会复制这个消息,所以在这种意义上伪造是可能的。

但从开始是不可能的。这两种属性——对Alice的意图的建立和对伪造的有限保护——都是该协议的真正显著特征。

我还没完全说明这个协议中的数字货币是什么。明确地说:这只是信息本身,即,这是一串代表数字签名信息的比特,“我,Alice,给了Bob一个infocoin”。以后的协议也会类似,因为我们所有数字货币的形式都将是越来越复杂的信息。

使用序列号让coin唯一可识别

第一个版本的Infocoin的有一个问题是,Alice可以不停地给Bob发送相同的签名消息。假设Bob收到了10份签名的消息,“我, Alice,正在给Bob一个infocoin”。这是不是意味着Alice给Bob发送了10个不同的infocoin?她的信息是否被意外地复制了?当这条信息向世界证明她打算转移一枚infocoin时,也许她是想骗Bob相信她给了他10个不同的infocoin。

我们想要的是一种使infocoin独一无二的方法。它们需要一个标签或序列号。Alice会在留言上签名:“我,Alice,给Bob一个infocoin,序列号为8740348”。然后,Alice可以在“我,Alice,给Bob一个infocoin,序列号8770431”的信息上签名,Bob(和其他人)都知道,一个不同的infocoin正在被转移。

为了让这个方案发挥作用,我们需要一个可靠的infocoin序列号来源。创建这种资源的一种方法是引入银行。这家银行将提供infocoin的序列号,跟踪记录谁拥有infocoin,并验证交易是否合法。

更详细地说,让我们假设Alice进入银行,并说“我想从我的帐户中取出一个infocoin”。银行把她的账户余额减少一个infocoin,并给她一个新的、从未使用过的序列号,比如1234567。

然后,当Alice想把她的“infocoin”转移给Bob时,她签署了“我,Alice,给Bob一个infocoin,序列号1234567”的信息。但Bob不只是接受infocoin。相反,他联系了银行,并验证了:(a)序列号的infocoin属于Alice;而且(b)Alice还没有花掉“infocoin”。

如果这两件事都是真的,那么Bob就会告诉银行他想接受infocoin,银行更新他们的记录,以显示这个序列号的infocoin现在已经在Bob的手中,而不再属于Alice。

让每个人都成为银

最后一个解决方案看起来很有希望。然而,事实证明我们可以做一些更有野心的事情。我们可以完全通过协议中去掉银行。这大大改变了货币的性质。这意味着不再有任何单一的组织来管理货币。当你想到中央银行控制货币供应量的超级权力,这就是一个巨大的变化。

这个想法是为了让每个人都是银行。具体来说,我们假定每个使用Infocoin的人都保存了一份完整的记录,就是那些持有infocoin的那些人。你可以把它想象成一个共享的公共总账本,里面记录了所有的infocoin的交易。我们把这个分布式账本称为区块链,这样的叫法,也是从我们接触到比特币协议之后才如此称呼的。

现在,假设Alice想把一个infocoin转移给Bob。她签署了“我,Alice,给Bob一个infocoin,序列号1234567”的信息,并向Bob发送了签名信息。Bob可以用他的区块链副本来检查,如果检查结果是真的,他就会向整个网络广播Alice和他的交易信息,每个人都会更新区块链的副本。

我们依然会有“序列号从哪里来”的问题,但这很容易解决,所以我将它放到后面来讲。一个更具挑战性的问题是,这个协议允许Alice 双花infocoin进行欺骗。她发送了一个签名信息:“我,Alice,给Bob一个infocoin,序列号1234567”给Bob,“我,Alice,给查理一个infocoin,和(相同的)序列号1234567”给查理。

Bob和查理都使用他们的区块链副本来验证infocoin是Alice的花费。如果他们几乎同时进行验证(在他们有机会相互知晓之前),他们都会发现,是的,区块链显示了coin属于Alice。这样他们就会接受交易,也会传播他们对交易的接受。

现在有一个问题。其他人应该如何更新他们的区块链?可能没有简单的方法来达成一致的交易账本。即使每个人都通过一致的方式更新他们的区块链,这里也仍然有一个问题,Bob或Charlie,他们中的一个,肯定将会被Alice欺骗。

乍一看,对于Alice来说,双花似乎很难实现。毕竟,如果Alice先将消息发送给Bob,那么Bob可以验证消息,并告诉网络中的其他人(包括Charlie)更新他们的区块链。一旦这种情况发生,查理就不会再被Alice愚弄了。

因此,只有一小段时间Alice进行双花。然而,有这样一段时间显然是不可取的。更糟糕的是,Alice可以利用一些技巧使这段时间变得更长。例如,她可以使用网络流量分析来找出Bob和Charlie在通信中可能存在大量的延迟时间。或者她可能会故意破坏他们的交流。如果她能放慢沟通速度,哪怕只是一点点,她欺骗其中一个人,进行双花会变得更容易一些。

我们如何解决双重支付的问题?显而易见的解决方案是,当Alice发送Bob一个infocoin时,Bob不应该尝试单独验证交易。相反,他应该向Infocoin整个用户网络广播可能的交易,并要求他们帮助确定交易是否合法。如果他们都决定交易没有问题,那么Bob可以接受infocoin,每个人都会更新他们的区块链。

这种类型的协议可以帮助防止双花,因为如果Alice试图双花支付infocoin给Bob和查理,网络上的其他人就会注意到,这个网络里的其他用户就会告诉Bob和查理这是有问题的交易,这样,这个双重支付的交易就不能通过。

更详细地说,让我们假设Alice想给Bob一个infocoin。就像以前一样,她签署了“我,Alice,给Bob一个infocoin,序列号1234567”的信息,并将签名的信息发给Bob。

和以前一样,Bob做了一次完整性检查,使用的是他的区块链副本检查,事实上,infocon目前仍属于Alice。但是在那个时候协议被修改了。Bob不只是继续接受交易。相反,他向整个网络广播了Alice的信息。网络上的其他成员检查Alice是否拥有这个infocoin。

如果是这样的话,他们会广播“是的,Alice拥有infocoin 1234567,现在可以转到Bob那里了。”一旦有足够多的人播放这个消息,每个人都会更新他们的区块链,以显示infocoin1234567现在属于Bob,交易完成了。”

该协议目前尚有许多不精确的元素。例如,“一旦有足够多的人传播这一信息”,这意味着什么?“足够”到底意味着什么?它不可能意味着网络上的每个人,因为我们事先并不知道当前谁在Infocoin网络上。

出于同样的原因,这并不意味着网络中某些固定比例的用户。我们现在不会试图让这些想法变得精确。相反,在下一节中,我将用描述的方法指出一个严重的问题。解决这个问题同时也会产生令人愉快的副作用,使这些想法更精确。

Proof-of-work

假设Alice想要在以上提及的网络协议中双花,她可以通过接管Infocoin网络来做到这一点。假设她使用一个自动系统在Infocoin网络上设置了大量不同的身份,比方说10亿。和以前一样,她试着把同一个infocoin转给Bob和查理。

但是当Bob和Charlie请求网络验证他们各自的交易时,Alice的傀儡身份在网络上出现了,他们向Bob宣布他们已经验证了他的交易,并且也告诉Charlie他们已经验证了他的交易,欺骗他们都接受了交易。

有一种巧妙的方法可以避免这个问题,使用一种被称为“工作量证明”的概念。这个想法是违反直觉的,并且包含了两个想法的组合:(1)人为地让网络用户验证交易的计算成本高昂;(2)奖励那些试图帮助验证交易的用户。

因为可以获得奖励,这样网络上的人们就会试图帮助验证交易,即使现在这个计算变得更昂贵了。验证交易成本高昂的好处是,验证不会再受某人控制的网络身份的数量影响,只能通过它们能够在验证中产生的全部计算能力来影响。

正如我们所看到的,有了一些巧妙的设计,可以使得作弊者需要耗费巨大的计算资源才可能成功,让作弊变得不切实际。

这就是工作量证明的要点。但要真正了解工作量证明,我们需要了解细节。

假设Alice向网络广播“I, Alice,给Bob一个infocoin,序列号1234567”的信息。

当网络上的其他人听到这个消息时,每个人都将其添加到他们已经被告知的正在等待的交易队列中,但是这个消息还没有得到网络的批准。

例如,另一个名为David的网络用户可能有以下等待交易的队列:

我,汤姆,正在给苏一个infocoin,序列号为1201174。

我,悉尼,正在辛西娅一枚infocoin,序列号为1295618。

我,Alice,正在给Bob一个infocoin,序列号1234567。

David检查了他的区块链副本,并且可以看到每个交易都是有效的。他希望通过向整个网络广播这种有效性的信息提供帮助。

然而,在此之前,作为验证协议的一部分,David需要解决一个困难的计算难题——工作量证明。如果没有这个难题的解决方案,网络的其他部分就不会接受他对交易的验证。

大卫需要解决什么难题?为了解释这一点,让h成为网络中每个人都知道的一个固定哈希函数——这个函数已经被构建到协议中了。比特币使用的是著名的SHA-256哈希函数,但任何加密安全的哈希函数都可以。

让我们给David的待处理交易的队列一个标签,l,它有一个我们可以引用的名字。假设David将数字x(称为nonce随机数)添加到l,并将其合并成哈希组。

例如,如果我们使用l = " Hello,world!"(显然,这不是一个交易列表,只是一个用于说明目的的字符串)和nonce x = 0(输出是十六进制)

h(“Hello,world!0”)=

1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64

David必须解决的难题是,通过工作量证明,找到一个特定的随机数 x,这样当我们将x添加到l,然后形成哈希组,输出哈希就会从一长串0开始。

通过改变难题所需的零数,可调整并改变解题的难易度。一个相对简单的工作量证明,在哈希开始时可能只需要3到4个零,而一个更困难的工作证明可能需要更长串的0,比如15个连续的0。在这两种情况下,上述试图找到合适的随机数 (x = 0)的尝试都失败了,因为输出不是从零开始。尝试x = 1也不起作用:

h(“Hello,world!1”)=

e9afc424b79e4f6ab42d99c81156d3a17228d6e1eef4139be78e948a9332a7d8

我们可以继续尝试不同的值来处理随机数x =2,3,....。最后,在x=4250 我们获得:

h(“Hello,world!4250”)=

0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9

这个随机数在哈希输出的开始给了我们一个四个0的字符串。这足以解决一个简单的工作量证明难题,但还不足以解决更难的工作难题。

使这个难题难以解决的事实是,密码哈希函数的输出行为就像一个随机数:即使只是很小的一点输入改变,哈希函数的输出也会完全改变,这很难预测。因此,如果我们希望输出哈希值以10个零开始,那么David在平均找到合适的随机数之前需要尝试不同的x值。这是一项非常具有挑战性的任务,需要大量的计算能力。

显然,通过在哈希函数输出中需要更多或更少的零,可以使这个难题或多或少地难于解决。事实上,比特币协议通过对上述工作量验证难题稍作修改,就可以很好地控制难度。

比特币工作量验证难题要求块头的哈希小于或等于被称为目标的数字,而不是要求从零开头。该目标会自动调整,以确保比特币区块平均需要大约十分钟才能进行验证。

(在实践中,要验证一个块需要多长时间,有相当大的随机性——有时一个新块在一两分钟内就会被验证,而其他时间则需要20分钟甚至更长时间。修改比特币协议是很简单的,因此验证的时间在十分钟左右达到峰值。我们不需要解决一个难题,而是需要解决多个难题;有了一些周全的设计,就有可能在一定程度上减少验证一个交易块的时间差异。)

好吧,让我们假设大卫很幸运,找到了一个合适的随机数, x,庆祝!(如下文所述,他将因找到随机数而获得奖励)。他将他认可的交易区块与x的值一起广播,而Infocoin网络的其他参与者可以验证x是对工作量证明的有效解决方案。然后他们更新他们的区块链,包括新的交易区块。

为了让工作量证明这个思想有任何成功的机会,网络用户需要激励来帮助验证交易。没有这样的激励,他们就没有理由消耗宝贵的计算能力--仅仅是为了帮助验证其他人的交易。

如果网络用户不愿意花费算力,那么整个系统就无法工作。解决这个问题的方法是奖励那些帮助验证交易的人。特别是,假设我们奖励成功地验证一个交易块的人一些infocoins。如果infocoin奖励足够大,就会激励他们参与验证。

在比特币协议中,这种验证过程称为挖矿。对于每一个经过验证的交易区块,成功的矿工都会得到比特币的奖励。最初,设置的奖励是50个比特币。但是对于每210,000个经过验证的区块(大约每四年一次),奖励减半。四年比例减半将一直持续,直到公元2140年。

那时,挖矿的奖励将会降至 111比特币/块。 比特币111实际上是比特币的最小单位,并被称为satoshi。因此,在2140年,比特币的总供应量将不再增加。然而,这并不能消除帮助验证交易的动机。

比特币协议的设计也使得矿工可以从一个交易订单中获取到一定量的比特币作为奖励,也就是帮助交易验证的交易费用奖励。在比特币交易的早期,交易费用大多为零,但随着比特币越来越受欢迎,交易费用也逐渐上升,并且在比特币挖矿奖励的基础上,还有额外的交易费用奖励。

您可以将工作量证明看作是批准交易的竞争。竞争中的每一项都需要一点计算能力。一个矿工赢得竞争的机会等于他们控制的总算力的比例。因此,例如,如果一个矿工控制了用于验证比特币交易的计算能力的百分之一,那么他们赢得竞争的概率大约为百分之一。

因此,在竞争中,提供了大量的计算能力,一个不诚实的矿工可能只有一个相对较小的机会来破坏验证过程,除非他们花费大量的计算资源。

当然,尽管令人鼓舞的是,一个不诚实的团体只有一个相对较小的机会来破坏区块链,但这还不足以让我们对货币产生信心。特别是,我们还没有完全解决双重支付的问题。

我很快就会分析双重支付。在此之前,我想在“infocoin”的描述中填写一个重要的细节。理想情况下,我们希望Infocoin网络能够就交易发生的顺序达成一致。如果我们没有这样的排序,那么在任何时候,谁拥有哪个infocoin可能还不清楚。

为了帮助实现这一点,我们将要求新的块总是包含一个指向区块链中已被验证的最后一个块的指针,以及块中的交易列表。(指针实际上只是前一个块的哈希)。因此,区块链通常只是一个线性的交易块,一个接一个,后面的每个块都包含一个指向前一个区块的指针:

有时,分叉会出现在区块链中。这可能发生,例如,如果两名矿工碰巧同时验证了一组交易——同时将新验证的区块广播到网络上,一些人用一种方式更新他们的区块链,另一些人则以另一种方式更新他们的区块链:

这正是我们试图避免的问题——交易发生的顺序已经不清楚了,可能还不清楚谁拥有哪个infocoin。幸运的是,有一个简单的想法可以用来移除任何分叉。

规则是这样的:如果发生分叉,网络上的人就会跟踪两个分叉。但是在任何给定的时间内,矿工只会在区块链的副本中使用最长的分叉。

例如,假设我们有一个分叉,其中一些矿工首先接收到A块,一些矿工首先收到B块。那些收到第一个区块A的矿工将继续沿着这支分叉链条挖矿,而其他的矿工则会沿着B分叉链条继续开采。假设在B分叉上工作的矿工成功地开采了一个区块:

当他们收到消息后,在fork A上工作的矿工将会注意到,B链条现在更长了,而会转而使用分叉B。很快地,在短时间内,fork A将停止工作,并且每个人都将在相同的线性链上工作,并且block A可以被忽略。当然,任何未完成的交易仍将在使用fork B的矿工队列中等待,因此所有交易最终都将被验证。

同样的,如果在分叉A上挖矿的矿工首先扩展了后面一个区块,在这种情况下,fork B的工作将很快停止,这样我们就还是拥有一个单一的线性链。

无论结果如何,这个过程确保区块链有一个商定的区块时间顺序。在比特币中,一笔交易不被确认,直到:(1)它是最长分叉中一个区块的一部分,并且(2)最长分叉中至少有5个块跟随它。在这种情况下,我们说交易有“6个确认”。这给了网络时间来达成一致的区块顺序。我们为Infocoin使用这一策略。

在了解了时间顺序之后,让我们回过头来想想如果一个不诚实的团体试图双花会发生什么。假设Alice想要给Bob和查理双重支付,一种可能的方法是让她尝试验证一个包含这两个交易的区块。

假设她有百分之一的计算能力,她偶尔会走运,并通过解决工作量证明来验证区块。不幸的是,在“Infocoin”网络中,人们会立刻发现“双重支付”,并拒绝她的交易生效,尽管解决了“工作量证明”的问题。所以这不是我们需要担心的。

一个更严重的问题是,如果她广播了两个独立的交易,她把同样的infocoin分别发给Bob和查理。例如,她可以将一个交易广播给一部分的矿工,另一个交易广播给其他矿工,希望以这种方式验证这两个交易。

幸运的是,在这种情况下,正如我们所看到的,网络最终会确认其中的一个交易,而不是两个。

因此,例如,Bob的交易可能最终得到确认,在这种情况下Bob可以自信地前进。与此同时,查理将会发现他的交易还没有得到确认,所以拒绝了Alice的提议。所以这也不是问题。事实上,知道这会是事实,没有理由让Alice首先尝试这个。

双花的一个重要变体是,如果Alice = Bob,也就是Alice想和查理发生交易,同时她也试图“花”在自己身上,还给她自己。这听起来应该很容易检测和处理,但是,当然,在网络上很容易设置与同一个人或组织相关的多重身份,所以这种可能性需要考虑。

在这种情况下,Alice的策略是等到查理接受“infocoin”,这是在最长的链中被确认6次之后发生的。然后,她将尝试在与查理的交易之前分叉,并添加一个包含她自己支付的交易的区块:

对Alice来说不幸的是,现在她很难赶上较长的链条。其他的矿工也不想帮她,因为他们要用更长的链条。而且,除非Alice能像网络中其他所有人一样快速地解决工作量证明——粗略地说,这意味着控制超过50%的算力——否则她就会继续落后下去。

当然,她可能会走运。例如,我们可以想象一个场景,其中Alice控制了一个百分比的计算能力,但是碰巧幸运地,在网络的其余部分找到了额外的区块之前,率先找到了6个额外的块。

在这种情况下,她可能会取得领先,并获得对区块链的控制。但是这个特定事件发生概率为111。沿着这些线进行更全面的分析表明,除非她能够以接近所有其他矿工的速度来解决工作量证明这个难题,否则Alice追赶上最长链条的概率是无穷小的。

当然,这并不是一个严格的安全分析来表明Alice不能重复消费。这只是一种非正式的似是而非的论点。事实上,最初引入比特币的论文并没有包含严格的安全分析,只是我自己在这里提出的一些非正式的论点。

安全界仍在分析比特币,试图了解可能存在的漏洞。您可以看到这里列出的一些研究,我在下面提到了“作者的问题”中的几个相关问题。在这一点上,我认为公平地说,关于比特币的安全问题,目前还没有定论。

工作量证明和挖矿的想法引发了许多问题。有多少奖励足以说服人们挖矿?infocoin供应量变化如何影响infocoin经济?“infocoin”的挖矿最终会导致数字货币集中在少数人手中?还是许多人手中?如果只是少数,这不会危及系统安全?

想必交易费用最终会达到平衡——这会不会带来不必要的摩擦、让小交易变得不那么令人满意吗?这些都是很好的问题,但超出了本文的范围。在以后的文章中,我可能会回到这些问题(在比特币的背景下)。目前,我们将继续专注于理解比特币协议是如何运作的。

作者的问题

我不明白为什么使用两阶段提交这样的更简单的方式无法防止双重支付 。假设Alice试图双重支付Bob和查理。这个想法是,Bob和查理将分别向Infocoin网络广播他们各自的消息,同时提出一个请求:“我应该接受这个吗?”然后他们会等待一段时间 - 也许是10分钟 - 听到任何可以证明这一点的反对者--Alice试图双花。

如果没有听到这样的说法(并且没有试图破坏网络的迹象),他们就会接受交易。这个协议需要加强对抗网络攻击,但在我看来,它是一个很好的替代想法的核心。这有效吗?与完整的比特币协议相比,它有什么缺点和优点?

在本部分的早期部分,我提到减少验证交易块所需的时间差异是一种自然的方法。如果这种差异减少太多,那么它会创造一个有趣的攻击可能性。

假设Alice试图以这样的方式分叉:(a)一个分叉开始于Alice支付给自己的区块,而另一个分叉以Alice支付给Bob的区块开始; (b)两个区块几乎同时宣布,所以大约一半的矿工将尝试挖矿两条分叉; (c)Alice利用她的挖矿算力试图保持分叉链条的长度大致相等,挖掘较短的分叉链条 - 这通常很难拉开距离,但如果验证时间越短于网络延迟时间,事情就变会变得容易;

(d)在两个分叉链条上开采了5个块后,Alice将她的采矿权力投入使Bob的交易更有可能被确认; (e)在Bob交易确认后,她将计算能力投入其他分支,并试图夺回领先优势。

这种平衡策略只有很小的成功机会。但是,虽然概率很小,但它肯定会比标准协议中的大得多,验证块的时间差异很大。有没有办法避免这个问题?

假设比特币挖矿软件总是从 111111这样来探索随机数。如果这是由所有(甚至只是一小部分)比特币矿工完成的,那么它会造成一个漏洞。

也就是说,有人可能仅仅通过开始一些其他(更大的)随机数来提高解决工作量证明的可能性。更一般地说,攻击者可能会以矿工探索随机空间的方式利用任何系统模式。

更一般地说,在本节的分析中,我隐含地假设了不同矿工之间的一种对称性。在实践中,会出现不对称现象,需要对这些不对称性进行彻底的安全分析。

比特

让我们从Infocoin走出来,描述实际的比特币协议。这里有一些新的想法,但有一个例外(下面将会讨论),他们大多是对Infocoin的明显修改。

要在实践中使用比特币,您需要首先在计算机上安装钱包程序。为了让您了解这意味着什么,下面是一个名为Multbit的钱包截图。您可以在左边看到比特币余额 0.06555555比特币,或者在我截图当天的汇率大约70美元- 以及右边最近的两笔交易,其中存放了0.06555555比特币:

假设你是一位在线商店的商人,并且你决定让人们用比特币支付。你要做的是,通过你的钱包程序生成一个比特币地址。作为回应,它将生成一个公钥/私钥对,然后对公钥进行哈希以形成您的比特币地址:

然后,您将您的比特币地址,发送给想要从您那里购买商品的人。你可以在电子邮件中这样做,甚至可以在网页上公开地址。这是安全的,因为地址仅仅是你的公钥的哈希,无论如何都可以安全地被世界所知。(稍后我会回到为什么比特币地址是哈希的问题,而不仅仅是公钥。)

然后,要向你付钱的人会产生一笔交易。让我们来看看实际交易0.31900000比特币的数据。下面显示的几乎是原始数据。它有三种变化:(1)数据已被反序列化; (2)已添加行号,以便参考; (3)我简化了各种哈希和公钥,只是放入每个数字的前六个十六进制数字,实际上它们要长得多。

这里是数据:

1. {"hash":"7c4025...",

2.  "ver":1,

3. "vin_sz":1,

4. "vout_sz":1,

5. "lock_time":0,

6. "size":224,

7. "in":[

8.   {"prev_out":

9.     {"hash":"2007ae...",

10.     "n":0},

11.   "scriptSig":"304502...042b2d..."}],

12."out":[

13.  {"value":"0.31900000",

14."scriptPubKey":"OP_DUPOP_HASH160 a7db6f OP_EQUALVERIFYOP_CHECKSIG"}]}

我们一行一行地看看这个。

第1行包含交易余数7c4025 ...的哈希,以十六进制表示。这用作交易的标识符。

第2行告诉我们,这是比特币协议版本1中的交易。

第3行和第4行告诉我们该交易分别有一个输入和一个输出。我将在下面讨论更多输入和输出的交易,以及为什么这很有用。

第5行包含lock_time的值,可用于控制交易何时结束。对于今天进行的大多数比特币交易,lock_time设置为0,这意味着交易立即完成。

第6行,告诉我们这个交易的大小有多少个字节(bytes),注意,这个不是交易的币的数量。

第7行到第11行定义了交易的输入。特别是,第8到10行告诉我们,输入的一些数据是来自于输出中较早期的交易,包括取了给定的哈希值,这是十六进制表示为2007ae ...。在N = 0告诉我们它是来自于那个交易中的第一个输出; 我们很快会看到交易的多个输出(和输入)是如何工作的,所以现在不要过多担心。

第11行包含发送钱的人的签名304502 ......,后面加一个空格,然后对应的公钥04b2d ...。再次说明,这些字符串都是十六进制的。

关于输入要注意的一件事是,没有明确地指定在这个交易中要花费多少比特币。事实上,所有从上一个交易的n=0输出的比特币都被花掉了。因此,例如,如果早期交易的n=0次输出为2个比特币,则将在该交易中花费2个比特币。

这似乎是一种不方便的限制——比如你试图用一张20美元的钞票买面包,却不能将这20美元进行切割。当然,解决办法是建立一种提供变更的机制。这可以通过使用具有多个输入和输出的交易来完成,我们将在下一节中讨论。

第12至14行定义了交易的输出。特别是,第13行告诉我们输出的值,0.319比特币。第14行有点复杂。主要需要注意的是字符串a7db6f…是这笔交易的预期接收者的比特币地址(用十六进制写)。

事实上,第14行实际上是比特币脚本语言中的一个表达式。我不会在这篇文章中详细描述这门语言,现在关注的是,a7db6f…是比特币的地址。

顺便说一句,你现在可以看到,比特币是如何解决我在上一节中提到的问题:比特币的序列号来自哪里?事实上,序列号的角色是由交易哈希实现的。

例如,在上面的交易中,接收方接收了0.319个比特币,这些比特币来自于先前带有hash 2007ae的早期交易的第一个输出。(第9行)如果您查看该交易的区块链,您会看到它的输出来自一个更早的交易。等等。

使用交易哈希而不是序列号有两个聪明的事情。首先,在比特币中,根本就没有任何单独的、持久的“coin”,它只是区块链中的一长串交易。这是一个聪明的想法,意识到你需要的不是持久稳固的coin,而是通过交易分类账获得。

其次,通过这样的操作,我们消除了任何中央机构发布序列号的需要。相反,序列号可以是自生成的,只需对交易进行哈希即可。

事实上,我们有可能继续追溯历史上的一系列交易。最终,这个过程必将终止。通过两种方式之一发生。第一个可能性是,你发现第一笔比特币交易,它包含在所谓的“创世区块”。这是一个特殊的交易,没有输入,但有50个比特币的输出。

换句话说,这笔交易建立了初始货币供应量。“Genesis创世块”是由比特币客户端单独处理的,我不会在这里详细说明,尽管它和上面的交易是类似的。你可以在这里看到反序列化的原始数据。

第二种可能是,当你跟踪交易的时候,最终你会到达所谓的coinbase交易。除了Genesis块之外,区块链中的每个交易区块都以一个特殊的coinbase交易开始。

这是一笔交易,奖励那些对交易进行验证的矿工。它使用与上述交易相似但不完全相同的格式。

上面我没有详细说明,在第11行中,数字签名的签名是什么。显然,要做的事情是让支付人在整个交易上签名(除了交易哈希之外,当然,这必须在以后生成)。

目前,这不是所做的事情——交易的一些部分被省略了。这使得交易的某些部分具有延展性,即,以后可以修改。

然而,这种可延展性并不包括支付的金额、打币者和收币者,这是以后不能改变的。我必须承认,我还没有深入了解这里的细节。我认为,比特币开发者社区正在讨论这种可塑性,并正在努力减少或消除这种可塑性。

具有多个输入和输出的交易

在上一节中,我描述了如何使用单个输入和单个输出工作的交易。实际上,用多个输入或多个输出创建比特币交易通常非常方便。下面我将讨论为什么这是有用的。但首先让我们看一看实际交易中的数据:

1.{"hash":"993830...",

2."ver":1,

3."vin_sz":3,

4. "vout_sz":2,

5. "lock_time":0,

6. "size":552,

7. "in":[

8.   {"prev_out":{

9.     "hash":"3beabc...",

10.       "n":0},

11.    "scriptSig":"304402...04c7d2..."},

12.   {"prev_out":{

13.       "hash":"fdae9b...",

14.       "n":0},

15.     "scriptSig":"304502...026e15..."},

16.   {"prev_out":{

17.       "hash":"20c86b...",

18.       "n":1},

19.     "scriptSig":"304402...038a52..."}],

20. "out":[

21.   {"value":"0.01068000",

22.     "scriptPubKey":"OP_DUPOP_HASH160 e8c306...OP_EQUALVERIFY OP_CHECKSIG"},

23.   {"value":"4.00000000",

24.     "scriptPubKey":"OP_DUPOP_HASH160 d644e3... OP_EQUALVERIFYOP_CHECKSIG"}]}

让我们一行一行地浏览数据。它与单输入单输出交易非常相似,所以我会很快介绍这个示例代码的意思。

第1行包含交易剩余部分的哈希。这用作交易的标识符。

第2行告诉我们,这是比特币协议版本1中的交易。

第3行和第4行告诉我们交易分别有三个输入和两个输出。

第5行包含lock_time。如在单输入单输出的情况下,这被设置为0,这意味着交易立即完成。

第6行告诉我们以字节Byte为单位的交易大小。

第7行到第19行定义了交易输入的列表。每个对应于之前比特币交易中的输出。

第一个输入在第8至11行中定义:

特别是,第8行到第10行告诉我们,输入将从交易的n = 0的输出中用哈希 3beabc ...取得。第11行包含签名,后面是空格,然后是发送比特币的人的公钥。

第12行到第15行定义了第二个输入,其格式与第8行到第11行相似。第16行到第19行定义了第三个输入。

第20行到第24行定义了一个包含交易两个输出的列表。

第一个输出在第21行和第22行中定义。第21行告诉我们输出值为0.01068000个比特币。像以前一样,第22行是比特币脚本语言的表达。这里最主要的是字符串e8c30622…是该多交易中接收者的比特币地址。

第二个输出定义在第23行和第24行,格式与第一个输出类似。

在这个描述中一个显而易见的奇怪之处在于,尽管每个输出都有一个与之相关的比特币值,但输入值却没有。当然,可以通过查询早期交易中的相应输出来找到相应输入的值。

在标准的比特币交易中,交易中所有输入的总和必须至少与所有输出的总和相同。(这一原则的唯一例外是Genesis区块,而在coinbase交易中,两者都增加了整体比特币供应。)如果输入总和高于输出,则多余部分用作交易费用,这些交易费用会支付给那些为当前交易成功完成验证计算的矿工们。

这就是多输入多输出交易!它们是单输入单输出交易的一个非常简单的变体。

多输入多输出交易的一个很好的应用是变化的想法。例如,假设我想向您发送0.15个比特币。我可以通过从之前收到0.2比特币的交易中花钱来做到这一点。当然,我不想给你全部0.2个比特币,解决方案是向您发送0.15个比特币,并向我拥有的比特币地址发送0.05个比特币。这些0.05比特币就是变化。

当然,这与你在商店中可能收到的变化有点不同,因为这种情况下的变化是你自己付出的。但宽泛的想法是相似的。

结论

这完成了对比特币背后主要思想的基本描述。当然,我省略了许多细节 - 这不是一个正式的规范。但是我已经描述了比特币最常见用例背后的主要思想。

虽然比特币的规则简单易懂,但这并不意味着很容易理解规则的所有后果。关于比特币可以说有更多的东西,我将在未来的帖子中对这些问题进行研究。

通过松散问题以结束此文:

比特币如何匿名?许多人声称比特币可以匿名使用。这一说法导致了丝绸之路等市场的形成(以及各种接班者),这些市场专门从事非法商品。但是,比特币是匿名的说法只是一个传说而已。

因为区块链是公开的,这意味着任何人都有可能看到每一个比特币的交易信息。虽然比特币地址并不直接与现实世界的身份相关联,但计算机科学家已经做了大量的工作以弄清楚如何去匿名化“匿名”的社交网络。区块链是这些技术的一个奇妙示范。

如果绝大多数比特币用户在不久的将来没有相对较高的信心和易用性,我会感到非常惊讶。信心不会高到足以实现信念,但会高到足以确定可能的目标。此外,身份是可以回溯性的,这意味着2011年在丝绸之路上购买药物的人仍可以基于2020年的区块链进行识别。

这些去匿名技术是计算机科学家所熟知的,因此推给NSA。如果国家安全局和其他机构已经对许多用户进行了匿名处理,我一点也不会感到惊讶。事实上,比特币经常被吹捧为匿名,这实在是讽刺。不是匿名,相反,比特币也许是世界上迄今为止最开放和最透明的金融工具。

你能用比特币致富吗?

也许。蒂姆奥赖利曾经说过:“钱就像汽车里的汽油一样 - 你需要对油量保持关注,否则你终将会抛锚 - 但是,一个好的生活并不单单是一个加油站的旅行!”人们对比特币的兴趣很大程度上来自于人们的生活使命—要找到一个真正的大型加油站。

我必须承认,这令人费解。我认为,更有趣的是,可以将比特币和其他加密货币视为实现新形式的集体行为的一种方式。这种想法是很吸引人的,它提供了绝妙的创造可能性,也具有社会价值,而且可能还会让你在银行里存下一些钱。但如果你最关心的是银行里的钱,那么我相信其他的策略更有可能成功。