开始的开始,我们都是孩子。最后的最后,渴望变成天使。歌谣的歌谣,藏着童话的影子。孩子的孩子,该要飞往哪儿去?——《北京东路的日子》
加密货币领域“开始的开始”,是中本聪2008年发布的文章《比特币:点对点电子现金系统》,在文章中,中本聪团队提出了一种新的“信任机制”,在不依靠银行的情况下解决“双花”问题。博文是对白皮书的粗浅理解,如有错误,欢迎指正。
简单来说,一个加密货币,就是一条签名链。
加密货币使用者分别有公钥(public key)和私钥(private key)。公钥任何人都可以看到,私钥只有持有者本人知道。以下是A转加密货币给B的过程,A的操作用红色标注,B的操作用蓝色标注

可以看到。A先把上一个签名和B的公钥共同进行哈希,再用A的私钥签名,把新的签名添加到签名链末尾。B用A的公钥来验证末尾签名,判断A是否拥有该加密货币。
但这有个问题。如果A同时拿B、C的公钥进行上述哈希操作,B、C拿A的公钥验证签名会发现都没有问题。这样A把一个加密货币转给了B、C两个人,发生了“双花”。
在传统模式中,银行会记账来解决“双花”问题。但人们对银行的信任在08年雷曼时刻受到了极大的动摇。人们发现,其实真正能信任的只有——“数学”。为了达成新的信任模式,解决“双花”问题,区块链横空出世了。
简单来说,区块链就是一个大家共有的、不能更改的记账本。
每一个参与记账的人,被称作一个节点。以下是甲、乙、丙三个节点通过工作量证明(POW)进行记账的过程。


每笔交易发生时,都会向所有节点广播,节点们会把过去十分钟的记录保存,用来进行下一步记账。

节点们把收集的交易记录储存成默克尔树(为什么用这种数据结构之后会说),得到默克尔值。

按照图示,构建区块,区块分为区块头和区块体。
区块头:版本号顾名思义;前一区块哈希值,指的是前一个区块头经过SHA256得到的256bit的Hash数;Merkel根在Step 2中算得;时间是区块构建的大概时间;Bits用来在Step 4中计算难度目标值;随机数,节点可以自由调整来完成哈希碰撞。
区块体:区块体第一条是挖矿奖励,凭空生成的比特币转给节点指定的钱包地址;之后就是节点之前收集的交易记录。

以区块链中第503829号为例。首先节点会根据区块头中的Bits来计算难度目标值,计算步骤如图示。接下来则是节点的工作过程:节点不断尝试随机数(大约43亿可能),使得区块头的SHA256值小于等于难度目标值,也称作逆哈希。一旦找到了满足条件的随机数,则工作完成。
为什么把不断尝试更改随机数叫做工作呢?这就要具体说一下哈希,哈希函数将任意长度的输入输出成固定的长度,它具有两个性质:不可逆、无冲突。不可逆指的是,知道x能很容易算出hash(x),但知道hash(x)不能算出x;无冲突指的是,不存在x和y,hash(x)等于hash(y)。但这两个性质过于理想,现实中哈希函数只能说:很难可逆、很难冲突(这使得通过尝试x来逆哈希成了可能)。节点的工作就是通过变换随机数,来变换x,从而变换hash(x),通过不断的尝试来完成逆哈希。

一旦节点找到了x,即完成了逆哈希,那么新的区块就诞生了。(例如满足503829区块难度目标的逆哈希值是0x36261012)新诞生的区块会被添加到区块链的末尾,并广播给所有的其他节点,该区块体中的交易信息也就被永远记录在了链上。
看完区块是怎么生成的,还有问题需要探讨,为何区块链有效?或者说,区块链为何不能更改交易信息,为何能解决“双花”?
个人认为核心在于,节点记账时,永远信任长的区块链,不信任短的区块链。
如之前所说,交易信息被节点们以默克尔树的形式存储。

假设当前区块链的长度是N,某坏人想更改N-1区块中“A转给B20BTC”这条交易信息。那么一旦该交易信息更改,hash0、hash01、Merkel值也随之改变,而Merkel值在区块头中,则区块头的SHA256值也改变了。被篡改了的区块链长度为N-1(因为第N个区块头记录的是原本未更改的SHA256值),而原来的区块链长度为N。当篡改者将长N-1的区块链广播出去时,其他节点会发现它短于自己正在工作的长为N的区块链,所以他们不会信任。
区块链解决“双花”依靠的是钱包的UTXO(未花费交易输出)以及区块链的分叉机制。
以比特币为例,所有比特币钱包的初始金额都是0,钱包不记录余额,而是通过UTXO来计算余额。

假设初始状况下,A钱包中有3条UTXO,B钱包中有0条UTXO。可以看到,A的UTXO第一条为挖矿奖励50BTC,第二条是C向A转了15BTC,第三条是C向A转了10BTC,可以计算得到,A钱包余额为75BTC。B钱包余额为0BTC。

当A试图向B转账20BTC时,会生成一条交易记录。交易记录左侧两条是输入,表示A打算消耗第二条和第三条UTXO来进行交易。右侧两条是输出,第一条UTXO预计进入B钱包,是转账;第二条UTXO预计进入A钱包,是找零。如果交易成功,A、B钱包中的UTXO会变成如上所示,计算UTXO可以得到,A钱包余额会变成55BTC,B钱包余额会变成20BTC。
为什么这就能解决“双花”呢?正如之前所说,交易记录会被广播给区块链的所有节点。假设节点“甲”接收到了交易记录,“甲”会判断左侧输入的两条UTXO是否在A的钱包中,如果在A的钱包中,则“甲”正在工作的区块会包含该交易记录,交易被完成,A和B的钱包改变。如果不在,则该交易是无效的,“甲”不会记录它。
这样,如果A打算将第二、三号UTXO先转给B,之后再转给C(尝试“双花”),这时会两种可能:
这两条记录都被同一个节点(假设是节点“甲”)看到了,“甲”会先记录第一笔“A转账给B 20BTC”的交易记录,更改A、B的钱包,而拒绝“A转账给C 20BTC”的交易记录,因为此时第二、三号UTXO已经不在A钱包中了。
节点“甲”只看到了“A转账给B 20BTC”的交易记录,节点“乙”只看到了“A转账给C 20BTC”的“交易记录”。不巧的是,他们工作速度都差不多,也就是说几乎同时完成了逆哈希,创造出新的区块,也在差不多时间将新区块广播了出去。这时,节点甲、乙、丙三个节点的区块链状态是这样的:

可以看到,“甲”和“乙”都坚信自己看到的交易记录,而节点“丙”因为同时收到了“甲”、“乙”的长度为4的区块链广播,也莫衷一是,所以在丙这里区块链出现了分叉。但这种分叉不会持续很久,因为节点“甲”和“乙”还在计算第五个区块,他们工作的速度总会有差别。
假设“甲”在计算新的区块中获胜了,它在“乙”之前广播了长度为5的区块链,根据“节点记账时,永远信任长的区块链,不信任短的区块链”这一原则,这时“乙”和“丙”都会切换到“甲”所在的区块链,所以“A转B 20BTC”被记录了,而“A转C 20BTC”被拒绝了,A和B的钱包会根据“A转B 20BTC”这一条交易记录来更改他们的UTXO。
如果仔细看上述两个问题:区块链为何不能更改交易信息?为何能解决“双花”?,能够发现,这一切都基于一个原则——节点记账时,永远信任长的区块链,不信任短的区块链。
但为什么节点会遵守这个原则呢?原因很简单,如果节点遵守这个原则,它还是有可能在新的区块挖掘中获胜(因为SHA256无规律,有可能走运很快完成逆哈希)得到挖矿奖励;而如果节点不遵守这个原则,即使它在较短的区块链上完成了逆哈希,但将短的区块链广播出去也不会被其他节点所接受(因为其他节点还秉持信长不信短的原则),最终挖矿奖励也无法兑现。
所以,如果坏节点想对区块链网络造成损害,唯一的办法是保证自己广播的永远是最长的区块链,这就要求坏节点拥有比其他所有人加起来都强的算力(还是因为SHA256无规律,所以坏节点必须计算到其他所有节点能计算到的),这也就是常说的“51%攻击”。
因为达成“51%攻击”的条件过于苛刻,所以我们能够信任区块链,让其进行交易的记录,来帮助我们防止交易记录的更改和避免“双花”问题。
2022年回看这篇14年前的文章,会发现其中的很多创新是革命性的。区块链创造了一种新的信任机制,让我们不借助中心化机构(例如银行)也能达成对账本的信任,这种新信任机制是如此重要,以至于可能改变我们生活的方方面面。
我们会将钱存入银行是因为“信任”,信任在我们需要的时候能把钱取出来使用;我们使用微信聊天是因为“信任”,信任我们发送的消息能够触达接收人;我们让子女进入学校接受教育是因为“信任”,信任学校能够给予基础的教育。过去的信任通常需要中心化机构来中介,例如上面提到的例子,因为我们相信在事情不对劲时,他们会干预且能够干预。但现在,不需要中心化机构,信任也能够达成了,虽然目前仅仅是对记账的信任,但作为“开始的开始”已经足够好。
今天是毛主席逝世46周年的日子,区块链这么一种自下而上的信任革命,某种程度上也能说是毛主义在科技领域的闪光。怀念他,但更重要是如何向前走。
今天就到这里,再见。
subscribe://

