整理了一下,关于区块链,希望这篇够用

2018-01-07 20:31:10 +08:00
 Taligent

作者寄言:毫无疑问,区块链将颠覆既有认知,敬那些伟大的前行者

Part 1. 站在巨人的肩膀上,密码朋克( CypherPunk )

在数字货币的探索实践中,比特币是目前表现最好的一个。说到比特币的缘起,就不得不谈到一个略显神秘的团体:密码朋克( CypherPunk )。这个团体是密码天才们的松散联盟。在比特币的创新中,大量借鉴了密码朋克成员的贡献。

探路者:

患了(ALS,即“渐冻人症“)的芬尼

Part 2. 创世块 - “财政大臣站在第二次救助银行的边缘”

2008 年 10 月 31 日纽约时间下午 2 点 10 分,在一个普通的密码学邮件列表中,几百个成员均收到了自称是中本聪的人的电子邮件。

“我一直在研究一个新的电子现金系统,这完全是点对点的,无需任何可信的第三方”

然后他将他们引向一个九页的白皮书,其中描述了一个新的货币体系。同年 11 月 16 日,中本聪放出了比特币代码的先行版本。

2009 年 1 月 3 日,中本聪在位于芬兰赫尔辛基的一个小型服务器上挖出了比特币的第一个区块——创世区块( Genesis Block ),并获得了首矿”奖励—— 50 个比特币。在创世区块中,中本聪写下这样一句话:

“ The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" “财政大臣站在第二次救助银行的边缘”

这句话是当天泰晤士报头版的标题。中本聪将它写进创世区块,不但清晰地展示着比特币的诞生时间,还表达着对旧体系的嘲讽。

**Part 3. **去中心化的账本系统

我们能不能构建一个去中心化的不依赖任何第三方的但却可信的记账系统呢?

这里,我们把记账系统中接入的每一台计算机称为“节点”。由于一致性的要求,每个节点却不能同时记账。因为节点所处的环境不同,接收到的信息自然不同,如果同时记账的话,必然会导致账本的不一致,造成混乱。

既然节点不能同时记账,那我们就不得不选择哪个节点拥有记账的权力。但是,如果指定某些特殊节点拥有记账的权力,势必又会与我们去中心化的初衷相违背。 这似乎成了不可能解决的问题。

**Part 4. **竞争记账和激励机制

中本聪设计的比特币区块链通过竞争记账的方式解决了去中心化的记账系统的一致性问题。

为了解释这个问题,我们引入一个新的名词“算力”。

所谓的竞争记账,就是以每个节点的计算能力即“算力”来竞争记账权的一种机制。在比特币系统中,大约每十分钟进行一轮算力竞赛(算力大小会决定赢得一轮竞争的概率,算力高的节点赢得算力竞争的概率更大),竞赛的胜利者,就获得一次记账的权力,这样,一定时间内,只有竞争的胜利者才能记账并向其他节点同步新增账本信息。

那么问题来了,在去中心化的系统中,谁来评定这个竞争结果呢?

比特币系统是通过一个称为“工作量证明”( proof of work, POW )的机制完成的。这个过程其实类似解决一到数学难题,我不需要知道你的解题过程,核对结果就可以了。

Part 5. 货币发行

算力竞争是要付出成本的,没有激励,节点就没有进行竞争的动力。在中本聪的设计里,每轮竞争胜出并完成记账的节点,将可以获得系统给予的一定数量的比特币奖励。而这个奖励的过程,同时也是比特币的发行过程。这种设计相当巧妙 —— 它将竞争的激励机制与货币的发行完美结合到一起,在引入竞争的同时,解决了去中心化货币系统中发行的难题。

Part 6. 所以什么是工作量( POW )证明?

工作量证明的基本含义其实很好理解,就是给计算机出一道难题,叫它去算出正确解。这个过程与验证码不同,验证码是易于被人理解,却不易被计算机理解。

比特币的工作量证明(难题的计算方法)都是围绕 SHA256 的,因为哈希值的伪随机特性可以帮助我们做概率估算。 现在我们为计算机出一道题,通过这道题,我会顺带关联出,比特币工作量证明的三个要素(证明函数、区块及难度值): 比如,我们设计工作量是这样的: 基本的字符串"Hello, world!" 加上(+) 多大的 nonce ( X )可以得到(=) 以 “ 0000 ” 开头的哈希结果(以 16 进制的形式表示)。

计算机的工作流程:

"Hello, world!0" => 1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64 "Hello, world!1" => e9afc424b79e4f6ab42d99c81156d3a17228d6e1eef4139be78e948a9332a7d8 "Hello, world!2" => ae37343a357a8297591625e7134cbea22f5928be8ca2a32aa475cf05fd4266b7 ... "Hello, world!4248" => 6e110d98b388e77e9c6f042ac6b497cec46660deef75a55ebc7cfdf65cc0b965 "Hello, world!4249" => c004190b822f1669cac8dc37e761cb73652e7832fb814565702245cf26ebb9e6 "Hello, world!4250" => 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9

那么 nonce 为 4521 就可以通过验证。

现在再给计算机增加难度(工作量)

我们将输入简单的变更为"Hello, world+整数值",整数值取 1 到 1000,也就是说,将输入变成一个由 1000 个值组成的数组:"Hello, world!1、Hello, world!2 …… Hello, world!1000"。然后对数组中的每一个输入依次进行上面例子中要求的工作量证明——找到前导为 4 个 0 的哈希散列。

我们会发现,进行计算的平均次数为 66958 次,十分接近 2^16 ( 65536)。数学期望的计算次数,就是我们要求的“工作量”。

Part 7. 区块 - 分布式账本

比特币的区块由区块头及该区块所包含的交易列表(账本)组成。区块头的大小为 80 字节,由 4 字节的版本号、32 字节的上一个区块的散列值、32 字节的Merkle Root Hash、4 字节的时间缀(当前时间)、4 字节的当前难度值、4 字节的随机数组成。

其中的第一笔交易是coinbase交易,这是一笔为了让矿工获得奖励及手续费的特殊交易(见货币发行)。

为了表明这个区块的多个交易,这里采用了Merkle Tree的数据结构。

这是为了解决,如果从一个稳定的服务器进行下载,采用单一 Hash 是可取的。但如果数据源不稳定,一旦数据损坏,就需要重新下载,这种下载的效率是很低的。而 MT 树的特性, 可以通过Merkle Root的 HASH 值,验证各个节点的完整性。

理解 Merkle Tree ( MT 树)

  1. MT 是一种树,大多数是二叉树,也可以多叉树,无论是几叉树,它都具有树结构的所有特点;

  2. Merkle Tree 的叶子节点的 value 是数据集合的单元数据或者单元数据 HASH。

  3. 非叶子节点的 value 是根据它下面所有的叶子节点值,然后按照 Hash 算法计算而得出的。

Part 8. 动态变化的难度值( difficulty )

难度值( difficulty )是矿工们在挖矿时候的重要参考指标,它决定了矿工大约需要经过多少次哈希运算才能产生一个合法的区块。比特币的区块大约每 10 分钟生成一个,如果要在不同的全网算力条件下,新区块的产生保持都基本这个速率,难度值必须根据全网算力的变化进行调整。简单地说,难度值被设定在无论挖矿能力如何,新区块产生速率都保持在 10 分钟一个。

难度的调整是在每个完整节点中独立自动发生的。每 2016 个区块,所有节点都会按统一的公式自动调整难度,这个公式是由最新 2016 个区块的花费时长与期望时长(期望时长为 20160 分钟即两周,是按每 10 分钟一个区块的产生速率计算出的总时长)比较得出的,根据实际时长与期望时长的比值,进行相应调整(或变难或变易)。也就是说,如果区块产生的速率比 10 分钟快则增加难度,比 10 分钟慢则降低难度。

新难度值 = 旧难度值 * ( 过去 2016 个区块花费时长 / 20160 分钟 )

工作量证明需要有一个目标值。比特币工作量证明的目标值( Target )的计算公式如下: 目标值 = 最大目标值 / 难度值

其中最大目标值为一个恒定值: 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

**Part 9. **验证工作量

我们可以把比特币矿工解这道工作量证明迷题的步骤大致归纳如下:

  1. 生成 Coinbase 交易,并与其他所有准备打包进区块的交易组成交易列表,通过 Merkle Tree 算法生成 Merkle Root Hash

  2. 把 Merkle Root Hash 及其他相关字段组装成区块头,将区块头的 80 字节数据( Block Header )作为工作量证明的输入

  3. 不停的变更区块头中的随机数即 nonce 的数值,并对每次变更后的的区块头做双重 SHA256 运算(即 SHA256(SHA256(Block_Header))),将结果值与当前网络的目标值做对比,如果小于目标值,则解题成功,工作量证明完成。 该过程可以用下图表示:

Part 10. 生成钱包地址

椭圆曲线算法生成的公钥信息比较长,压缩格式的有 33 字节,非压缩的则有 65 字节。地址是为了减少接收方所需标识的字节数。比特币地址的生成步骤如下:

  1. 生成私钥与公钥

  2. 将公钥通过 SHA256 哈希算法处理得到 32 字节的哈希值

  3. 后对得到的哈希值通过 RIPEMD-160 算法来得到 20 字节的哈希值 —— Hash160

  4. 把版本号+Hash160 组成的 21 字节数组进行双次 SHA256 哈希运算,得到的哈希值的头 4 个字节作为校验和,放置 21 字节数组的末尾。

  5. 对组成 25 位数组进行 Base58 编码,就得到地址。 下图以非压缩格式的 65 字节公钥示意上述过程:

由于椭圆曲线乘法以及哈希函数的特性,我们可以从私钥推导出公钥,也可以从公钥推导出地址,而这个过程是不可逆的。也正因如此,在整个比特币系统中,私钥是最关键的部分。私钥泄露也就意味着丢失了一切。 我们要花掉一个地址上的资产,需要构造一笔交易,同时使用这个地址对应的私钥签名。而如果我们要将资产转移到某个地址上,只需要转账给他公开的地址就行了。

最后一段小字,写给想看的人… 我们正生活在一个社会,这个社会,压抑,无趣,和缺少真相。 The game is on, the fight for net neutrality is long. Toast for freedom.

**Final. **想了解更多

@作者 WeChat ID: MONFUR

4250 次点击
所在节点    问与答
7 条回复
HayesTsai
2018-01-07 22:14:29 +08:00
赞楼主一个,总结的很到位。日前研究过一段难度值调整算法,其实出块过程是一个泊松过程(多次伯努利实验之和),难度值调整算法也都根据这个去建模出块过程。但是糟糕的是,现在的出块时间还是很不稳定的,也就是出块时间的方差很大,短则几秒,长则十几个小时,这个问题目前还没有很好的解决办法,原因之一是现实世界中的算力不是平稳的,经常发生大的颠簸,这个应该算是一个潜在的问题吧,有 V 友有了解的话可以一起探讨探讨。
vcfghtyjc
2018-01-07 22:47:57 +08:00
都是基本概念的整理吧,没什么新东西。可以研究一下当前区块链技术的缺陷,以及未来可能的应用方向?
Taligent
2018-01-07 22:57:02 +08:00
感谢建议
cmlz
2018-01-08 01:05:51 +08:00
只说了 POW 没说到 POS。
hanbing135
2018-01-08 07:16:04 +08:00
赞 不过似乎是总结
grikr
2018-01-08 07:53:20 +08:00
写的不错,赞
Taligent
2018-01-08 15:58:52 +08:00
谢谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/420871

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX