2018 年 3 月

第 33 卷,第 3 期

区块链 - 区块链基础知识

作者 Jonathan Waldman | 2018 年 3 月

早在 1999 年,文件共享网络 Napster 就出现了,可方便用户在混合对等网络(之所以使用“混合”一词是因为它使用了中央目录服务器)上轻松共享音频文件(通常包含音乐)。文件共享网络不仅仅可用于共享音乐文件,还允许所有用户保留这些共享文件的副本。这样一来,单个数字资产就会跨全球网络生成无限个合理副本。这项技术简单易用,只要有计算机,任何人都可以利用它。这让备受尊崇的淘儿唱片业绩意外下滑。到 2006 年,淘儿唱片被迫关闭了它在美国国内的所有 89 家门店。

2008 年,次贷危机爆发。在此期间,成立已久、实力强大的美国金融机构和保险公司纷纷宣布破产或濒临破产边缘。在这种情况下,联邦政府必须立即干预,以免爆发全国性乃至全球金融危机。这一重大事件让民众对中央银行心存疑虑,并揭露了资金账本不接受公众监督的危险性。2008 年 3 月,哈特兰支付系统公司数据泄露曝光了超过 1.3 亿信用卡号,导致其中许多信用卡号后来被盗用于进行欺诈性购买。

这些事件说明了生活在数字化互联世界的极大危险性,不仅依赖交易费用生成中间商,还易受数字攻击、贪婪和犯罪行为影响。学术挑战在于,如何创建脱媒数字基础结构,用于在所有者之间公开可靠地转让(而不是复制和共享)数字资产,既没有腐败或不可靠的中央集权机构,而又安全且可信任。

比特币区块链入门

2009 年 1 月 3 日,出现了一种新型基础结构,似乎是在历史背景下应运而生。它挖矿获得 50 个数字币,并将它们记录在防篡改公用账本上。此帐本被复制到由已联网计算机组成的分散式对等网络上。这 50 个加密货币单位就称为“比特币”,记录为创世区块,即被认为是比特币区块链的第一个链接。

这种由区块链提供技术支持的加密货币的非凡之处在于,不通过任何信任或监管机构(如银行或政府)验证每笔交易。此外,它还让交易脱媒,即使用不涉及中间商(如代理或代理机构)的全球网络,在全球范围内转让数字货币。由于依赖新式加密,因此区块链中的数据是防篡改的匿名数据。此外,因为给定区块链被复制到对等网络中的每个节点,所以没有单一故障点,确保了这项技术的可用性和可靠性。

自比特币推出以来,区块链技术快速发展,不断成熟完善。区块链实现细节的差异很大,这就让区块链研究成为一项不断变化且非常复杂的庞大任务。实际上,“区块链”一词不再只适用于通常所说的加密货币,特别是比特币。区块链正在不断优化和完善,旨在成为更快更智能的技术。实际上,一些区块链技术允许编写脚本来支持智能合同,这样就可以将自定义规则应用于交易。这样一来,区块链就已演变成一种新型可编程的防黑客存储技术。正是出于这一原因,IT 专业人士、企业、金融机构等强烈要求发挥它的真正潜能。

如果一直在局外观望区块链,现在是时候急起直追了。这是一篇介绍性文章,不可能涵盖所有区块链技术的详尽技术细节,每项技术都有自己的规则、功能和自定义。不过,我在本文中介绍了许多概念,将有助于读者了解众多新式区块链技术所依据的核心技术基础。

区块链的工作原理

比特币区块链是世界上首个区块链技术实例。由于这种特质,“区块链”经常被误解为与比特币密不可分。不过,新式区块链技术产品/服务跟踪除数字货币外的数字资产,此类区块链的工作原理与比特币区块链大不相同。此外,比特币区块链还推广了一种观念,即区块链是虚拟化银行账本的数据结构,具体是通过跟踪借贷,同时提供有创意的加密解决方案,以有效禁止加密货币单位的双重支出。因此,“数字账本”和“双重支出”术语就与加密货币区块链关联起来。不过,这两个术语分别广泛应用于跟踪所有权和强制单次转让数字资产。看到这两个术语时,不要以为它们只是指面向加密货币的区块链技术。

从本质上讲,区块链是一种防篡改数据结构,可以跟踪在所有者之间传递的有价值或感兴趣内容。这里所指的“内容”可以是任何一种数字资产,如数字币、Word 文档或 Microsoft Surface 平板电脑序列号。实际上,只要是可以与唯一数字指纹关联的项,就能在区块链上进行跟踪。区块链要求转让数字资产所有权,而不是复制或共享,解决了所谓的“双重支出”问题。不过,区块链技术的有趣之处在于,它不仅建立了协议和强制执行交易规则,还能够让计算机分布式网络中的节点自我监督整个操作。而且,它是在没有中央服务器或信任颁发机构的情况下,迅速在全球范围内完成了这一非凡壮举。这样的前景激起了人们的兴趣,希望通过它来消除中间商、减少或停征交易费用,同时让企业和使用者都能提高商务效率。

区块链核心组成部分

比特币区块链网络是公用的。也就是说,任何人可以随时随地参与进来。不过,新式区块链产品/服务(如 Microsoft Azure 托管区块链)可以配置为公用网络、专用网络或特权网络。虽然区块链是分散的,但分散的含义需要进一步澄清。正如 Vitalik Buterin 所解释 (bit.ly/2tEUYyT),“分散式区块链”是指它们“不仅在政治上是分散的(不受任何监管),在体系结构上也是分散的(无基础结构中心故障点),但它们在逻辑上并不是分散的(有一个共同商定的状态,且系统就像一台计算机一样运转)”。 分散化提供容错、攻击防御和勾结防御(稍后我将介绍工作量证明,届时此含义就会变得清晰明了)。

若要了解如何设计公用区块链,需要了解加密哈希、公钥加密 (PKC)、二叉哈希链(特别是 Merkle 树)和一致性算法。我将简要回顾一下这些概念,并介绍区块链是包含交易哈希链的哈希链。掌握此嵌套哈希链概念后,就会理解区块链技术的基本设计。

加密哈希:虽然有许多单向加密哈希算法变体,但通常选用的是 SHA-256 (bit.ly/29kkpft)。这是一种单向哈希函数,接受最大为 (264-1)/8 字节的消息,并返回 32 字节的哈希值(64 个十六进制字符),十进制范围介于 0 和约 1.16 x 1077之间。为了能够正确看待数量级,需要指出的是,一滴水大约包含 5 x 1012 个原子;可观测宇宙的原子数估计介于 1078 和 1082 之间。调整消息中的任何字符,并重新计算 SHA-256 哈希值,就可以生成全新的哈希值。(若要试验,请访问 onlinemd5.com,并将文件或文本校验和类型设置为 SHA-256。)

如果输入相同,SHA-256 算法始终生成相同的定长输出。对于区块链技术,使用 SHA-256 加密哈希的价值在于,它们是唯一的,可同时用作数字指纹和校验和。此外,(作为惯例)单向哈希函数不能进行解码。以我名字的 SHA-256 值为例:8F12D83BA54AC0EA7687AD4AFDE5E258BBFF970AA8D60C6588381784C502CA8E。由于这是哈希值,因此实际上无法使用算法反向推出我的名字。(一种黑客技术利用的是彩虹表,其中列出了已计算出的常见字符串(如“密码”)哈希值,但这也不是通过算法来反向推出哈希。为了抵御此类攻击,惯例做法是通过附加随机字符串(称为“加密盐”值),修饰要哈希处理的字符串。)

如果没有 SHA-256 生成器可用,请参阅图 1 中的表,它表明不同长度的字符串始终生成 64 位十六进制哈希值,以及对任何字符串稍作更改就会导致结果完全不同。

图 1:使用 SHA-256 算法对各种长度的字符串进行哈希处理

输入字符串 SHA-256 哈希值
m 62C66A7A5DD70C3146618063C344E531E6D4B59E379808443CE962B3ABD63C5A
M 08F271887CE94707DA822D5263BAE19D5519CB3614E0DAEDC4C7CE5DAB7473F1
M1 2D214CA69B86C255BE416D42CCA977A59B34A7492873105522C35015FAB806F0
M2 0892A10ECE1F933EE98F5D554601B28F8437801D1AA1B77799E4035DDCB6950C
三月 9D95A2CF0D7180B5089691163B188A7203B0CDE179346B8CFAA8AB6C2C3E6414
March 1, 2018 767328E7367048FA9DB37354CFA43DBB1691E8330DB54D54F52C1A444CA2E680
March 2, 2018 CCF33BF1C08B74EDE6A7C15C56EEC16269D83967670032ACDA6EE395361B7595

有时,哈希值会进行双重哈希处理。也就是说,通过应用第二轮 SHA-256 算法,再次对第一个哈希值进行哈希处理。如果对图 1 中的值进行双重哈希处理,最终会生成图 2**** 中的结果。

图 2:对图 1 中的值进行双重哈希处理

输入字符串 双重 SHA-256 哈希值
m A5FCE7E78734EC317F83F9019C80FFAF2508689B06EFA02191495A7D21FECE9A
M 6F6DCF58526B0D29EE664A708A939B7CDAC124A6A8569FCACE46FEAD38868E2E
M1 6C5D08BE9FFBBABD24B5F19AFFE6590FD402D347A50B519A59D40E15DCC0A6CB
M2 B2307311CC5877D5A581EDC821F3BFD5F99EB4E3B1D1B4009D9545BCF07E2E1A
三月 B5410E155022AE6EB22CA21FADEDE65F0F7296DE14CA1D7A720A4937BD23AA5D
March 1, 2018 345DD725FEE80F8C5953A66C1495605E4ED01C4CE5AEF6C0A6D238999266A1A6
March 2, 2018 3E85B3D910BA77F88ECD5E24D1396457C532C73B89C032DED9AD0CBB4D4D9794

公钥加密:回顾一下,区块链的主要功能之一是,跟踪数字资产的所有权。相关数字资产可能一文不值,也可能价值数百万美元。因此,所有权测试必须确保所有者是无法假冒的。为了在数字领域进行此类测试,区块链利用的是 PKC,以便所有者能够对资产进行数字签名,以证明所有权和授权资产转让。与使用一个私钥加密和解密消息的对称密钥加密不同,PKC 使用非对称密钥加密。

由于数字资产所有权的精确验证算法对区块链至关重要,因此它们采用依赖椭圆曲线数字签名算法 (ECDSA) 的高安全系数公钥/私钥对生成策略。ECDSA 的优点在于,它创建的密钥虽然长度较短,但加密安全系数高于常用算法数字签名授权 (DSA) 生成的相同长度密钥。只要需要,用户就可以访问软件应用程序,以使用 ECDSA 生成加密密钥对。用户必须保留私钥备份,因为必须使用此密钥,才能转让或利用在区块链中存储的数字资产的价值。如果只有权访问私钥/公钥对中的私钥,可以重新生成公钥,因为这两个密钥之间存在一种数学关系。不过,无法通过公钥生成私钥。也就是说,如果只备份一个密钥,请务必备份私钥!

通常采用两种方式之一使用这些密钥。第一个用例(见图 3)是,希望有人向你发送只有你才能打开的加密消息。为此,请向对方提供你的公钥,让其使用此公钥加密文档,具体是通过软件应用加密算法,并生成已加密文本(即加密版消息)。然后,对方就会向你只发送已加密文本。由于对方使用的是公钥来加密文档,因此必须使用正确配对的私钥才能解密文档。

希望有人向你发送只有你才能打开的加密文档/消息时使用 PKC
图 3:希望有人向你发送只有你才能打开的加密文档/消息时使用 PKC

第二个用例(见图 4)是,希望加密消息并证明它确实由你发送。为此,请使用私钥创建文档的已加密文本。然后,将此已加密文本发送给其他人。对方会使用你的公钥来解密文档。由于只有你的公钥才能解密文档,因此收件人可以认为文档是由你的私钥加密。也就是说,除非私钥被盗用,否则文档就是由你发送。

希望向其他人发送加密文档/消息并证明它确实由你发送时使用 PKC
图 4:希望向其他人发送加密文档/消息并证明它确实由你发送时使用 PKC

第三个用例使用 PKC 通过数字签名流程来证明数字资产所有权。在此用例(见图 5)中,假设 Bill 已编写具有法律约束力的 Word 文档,他需要通过电子邮件方式将文档发送给 Susan。Susan 希望确定她从 Bill 处收到的文档副本确实是由 Bill 发送,而且在途中尚未被篡改。Bill 先创建 Word 文档的 SHA-256 哈希,并将值记录为 H(W)。接下来,他使用自己的私钥对文档哈希进行加密,生成 Enc(H(W)),再向 Susan 发送 Word 文档(可视情况加密)和 Enc(H(W)) 值(这是 Bill 对文档 W 的数字签名)。

使用 PKC 和加密哈希对文档/消息进行数字签名
图 5:使用 PKC 和加密哈希对文档/消息进行数字签名

Susan 通过她收到的 Word 文档副本重新计算 H(W) 值,再使用 Bill 的公匙解密 Enc(H(W)) 值(见图 6)。如果 Susan 计算的哈希值等于解密的 H(W) 值,Susan 可以得出下列结论:Bill 对文档进行了签名,并且她收到的副本与 Bill 签名的文件完全相同。

使用 PKC 和加密哈希验证文档/消息是否由预期方进行签名
图 6:使用 PKC 和加密哈希验证文档/消息是否由预期方进行签名

使用哈希和 PKC,区块链维护了数字资产所有权的交易历史记录。交易数据对象相互链接,形成称为“哈希链”的数据结构。工作原理是,每个交易记录都会构成消息 (m),此类消息先通过函数 (H) 进行哈希处理,再通过所有者私钥 (s) 进行签名。(惯例做法是,使用“secret”的首字母“s”表示私钥,以免与表示公钥的“p”混淆。) 这就生成了签名 (sig):

sig = signature(H(m), s)

在数字资产从一个所有者转让给另一个所有者后,新所有者会检查、验证它的数字签名并进行数字签名,再将它注册为哈希链上的新节点。尽管实现细节因区块链技术和版本差异很大,但对于所有这些技术和版本,基本概念是相同的。例如,如图 7 所示,Bill 是数字资产的所有者,他使用私钥发起向 Susan 转让数字资产。Susan 的交易记录使用 Bill 的公钥来验证他的签名。在此之后,Susan 使用公钥对数字资产进行签名,让 Susan 成为新所有者。这就会新建交易记录,即交易哈希链上的新链接。

交易哈希链使用数字签名转让数字资产所有权;每个交易记录都保留有对哈希链中上一个交易的加密反向链接
图 7:交易哈希链使用数字签名转让数字资产所有权;每个交易记录都保留有对哈希链中上一个交易的加密反向链接

此交易哈希链受加密保护,并且防篡改。对交易 0 的任何更改都会导致 Sig0 变化,要求更新在交易 1 中存储的哈希值,以及哈希链上的每个后续交易。

图中的交易对象包含数据。每个交易包含的数据因各个区块链实现而异。所以鉴于此,我已抽象化处理基础数据,因为要明白的要点是,哈希链是一种加密链接的交易链,即由上一个所有者的交易记录的哈希值链接起来。(在加密货币区块链中,每个交易对象都包含数字货币输入和输出列表,以及元数据(如时间戳和可选的交易费用)。这些加密货币输入和输出提供对财务账本进行精确建模所需的交易详情。)

Merkle 树:一些区块链使用另一种哈希链捆绑交易,即二叉哈希链或 Merkle 树。完整的 Merkle 树称为“二叉树结构”,因为它从根开始每个级别都有两个分支,如图 8 所示。

Merkle 树是一种生成 Merkle 根哈希的二叉哈希树;此数据结构可以有效添加叶节点,并计算新 Merkle 根,而无需完全重新计算
图 8:Merkle 树是一种生成 Merkle 根哈希的二叉哈希树;此数据结构可以有效添加叶节点,并计算新 Merkle 根,而无需完全重新计算

Merkle 树的创建方式是,计算每个交易对象中数据的 SHA-256 哈希,以创建一系列叶节点(比特币区块链对每个 Merkle 节点进行双重哈希处理;双重哈希处理有助于在 SHA-256 算法中发现漏洞的情况下,强化哈希结果中的加密值)。Merkle 树要求必须有偶数个叶节点。也就是说,如果开始时为奇数,惯例做法是复制最后一个叶节点。然后,每一对叶节点一起进行哈希处理,生成新哈希值。在图 8 中,叶 A 将交易 A 的哈希显示为 H回答:;叶 B 将交易 B 的哈希显示为 HB 表示同一个数字。此模式继续应用于每个树级别,一直应用到最终的根节点。根节点的哈希值是树中其他所有哈希和的加密哈希和。对任意叶节点中数据的任何更改,都会导致重新计算的 Merkle 树根哈希值发生变化。

Merkle 二叉哈希树结构具有一些优点。例如,它可以轻松更新交易中的数据,并计算新 Merkle 根哈希,而无需从头开始生成整个 Merkle 树。例如,如果(图 8**** 中突出显示的)交易 E 发生了变化,只需高效地为树中每个级别反向计算一次新哈希,一直计算到 Merkle 根即可。因此,先计算新叶哈希 HE;再计算 HEF ,依据为 HE 和 HF;再计算 HEFGH ,依据为 HEF和 HGH;再计算新 Merkle 根哈希,依据为 HABCD 和 HEFGH。更新 Merkle 根哈希只需进行 4 次计算,而从头开始生成 Merkle 树则需要进行 15 次计算!

生成区块链

若要生成区块链(见图 9),必须以某种方式将包含交易的二叉哈希链数据对象提交到可供所有人使用的防篡改数据存储中(请注意,这是公用区块链,网络上的任何节点都可以对它执行读取或写入操作)。由于 Merkle 树结构包含交易且防篡改,因此似乎可以用作区块链。不过,存在几个问题。Bill 必须信任以代理身份处理他的数字资产转让请求的服务或网站,并且必须信任暂留哈希结构的服务器,才能将他的数字资产发送给 Susan。如果没有处理新交易的中央节点,或没有委托处理事务的中央集权机构,任何节点都可以处理 Bill 的挂起交易。具有超高处理能力的未授权节点或基准节点会纵容无效或欺诈性交易发生,这些交易可能会传播到可靠节点。为了解决此问题,网络可以尝试随机分配一个节点来处理 Bill 的交易,但这会再次集中控制权,并要求相信随机数生成器确实是在强制实现随机性。为了杜绝此问题,区块链使用一致性算法,如下所述。

区块链由区块组成,这些区块继而包含交易哈希树;区块链上的区块反向链接到前面的区块,并通过工作量证明算法进行验证
图 9:区块链由区块组成,这些区块继而包含交易哈希树;区块链上的区块反向链接到前面的区块,并通过工作量证明算法进行验证

一致性算法:区块链技术通过遵循规定如何添加和维护区块的协议,杜绝了集中数据存储和信任授权问题。为此,它们强制执行区块链生成一致性算法。一致性算法有多种不同的种类,我将介绍的是工作量证明 (PoW) 算法工作原理。

PoW 的依据是,网络上的一个节点需要通过产生的费用和解决计算难题所需的耗时,证明它的合理意图。为了让节点参与此类系统并遵守规则,网络提供激励(通常是金钱奖励)。也就是说,节点运算符向区块链添加区块时就会得到报酬。为了赢取金钱奖励,节点必须验证所有交易(以确保它们符合区块链的特定规则),再解决加密难题。

我在前面提到过,中央集权机构可以随机分配节点来处理一批新交易。这种方法需要使用中央随机数生成器,但它可能会有缺陷、遭黑客攻击或禁用。不过,为节点提供待解决的难题可以带来预期效果。无法预先确定第一个解决难题的节点,这就形成了网络节点的某种不可预测性。无需中央集权机构,这是区块链技术的关键创新之一。我还提到了区块链是分散式的,因此提供勾结防御。 由于 PoW 在计算能力方面投入了时间和成本,因此任何一个节点或一组节点都几乎无法在网络上进行勾结,并且与其他对等节点相比,具有区块链生成优势。(存在“51% 攻击”风险,表明如果一组节点的计算能力最终达到 51%,就会出现勾结;但如果采用 PoW 一致性算法,就不可能发生这种攻击。)

为了构造交易区块,节点需要获取在网络上存储的未处理交易,并生成 Merkle 树来计算 Merkle 根哈希。因此,候选区块包含交易列表和区块标头,其中标头包括 Merkle 根哈希值、当前时间戳和 PoW 难度级别(有时还附加有标头数据)。然后,它必须解决 PoW 难题,这涉及计算双重哈希的整个 256 位区块哈希值,再找到 32 位数字 nonce。可以将此数字与哈希值连接,生成 288 位数字的哈希,这样结果中就带有一定数量的前导零。此 32 位 nonce 介于 0 和 232 (4,294,967,295) 之间。因此,惯常做法不是直接尝试猜测 nonce,而是从 nonce 0 开始,生成 SHA-256 哈希,并确定它是否有目标数量的前导零(也就是说,生成的哈希值小于目标值);如果没有,节点会增加 nonce 值,并再次尝试。如果节点尝试了所有 nonce 值都未能解决难题,它会重新计算区块哈希值。这就保证生成不同的区块哈希值,因为区块标头中的时间戳包含在区块哈希计算中。节点可以随时选择一批不同的挂起交易,以供添加到新区块中(或添加自上次检查起可能出现的新挂起交易),这会更改 Merkle 根哈希值,并会连同时间戳一起更改新计算出的区块哈希值。每次重新计算区块哈希时,节点都会再次遍历所有超过 40 亿个 nonce。

随着时间的推移,网络上的某节点将会解决加密难题。此时,它会将新区块添加到区块链副本末尾(每个节点维护一个区块链副本),再将新区块广播到网络上的其他所有节点,这样它们就可以更新自己的区块链副本了。如果节点广播新区块,其他节点不会简单地相信新区块是有效的,它们会通过验证区块向自己证明这一点。若要进行验证,节点只需通过计算与 nonce 值连接的区块 SHA-256 哈希,即可验证 PoW 难题解决方案,并验证生成哈希的结果是否包含区块 PoW 难度值所指定数量的前导零。

顺便提一句,在某些区块链上,协议会不断调整 PoW 难度值,以便按规定的时间间隔将新区块添加到区块链中。这种持续调整是必要的,因为节点在网络中不断出现和消失,导致节点的平均计算能力总是在变化中。请注意,在 PoW 中,向区块链添加区块是有激励的。因此,节点管理员通常会增强硬件,以竞争获取奖励。在比特币区块链上,难度值每 2016 个区块调整一次,这样区块就可以每区块 10 分钟的平均速率继续添加。

有时会出现分支。这是因为在大型网络中,新区块传播需要时间。在传播过程中可能会出现的情况是,另一个节点解决 PoW 难题,向区块链副本添加新区块,再在网络上广播区块链。接收节点始终都会向区块链副本添加有效区块,而且由于每个区块都以加密方式连接到上一区块,两个不同节点发布的两个新区块会在链末尾生成链接到同一个区块的分支。不过,没关系。随着时间的推移,节点会在协议认为的“最长链”末尾添加新区块。 例如,对于给定分支,最长链可以定义为具有最新区块时间戳的链。随着时间的推移,一个分支会在长度方面占上风,已放弃(更短)分支中的区块会遭删除,同时它们的交易会返回到未处理交易池中。

总结

本文介绍了如何构造由分散式对等节点网络上的加密链接区块组成的公用区块链,每个链接区块都有自己的加密链接交易哈希链。我介绍了区块链技术的基础知识,将重心尽量不放在任何单一实现上,而是放在它们共有的一些更为典型的技术特性上。如果希望进一步探索此主题,建议选择一种区块链技术(如比特币、以太坊或 Ripple),并尝试掌握它具体实现的详细信息。若要亲自体验区块链,不妨了解一下 Azure 托管区块链产品/服务 (bit.ly/2Gj2zaC)。


Jonathan Waldman 是一名 Microsoft 认证专家,专攻软件工效学,从 Microsoft 技术诞生之际便一直研究这些技术。Waldman 是 Pluralsight 技术团队的成员,目前负责机构和私营部分的软件开发项目。可以通过 jonathan.waldman@live.com 与他取得联系。**

 衷心感谢以下 Microsoft 技术专家对本文的审阅:James McCaffrey


在 MSDN 杂志论坛讨论这篇文章