比特币、区块链基本原理

References

Note

正如阮一峰所说,抛开技术细节,其实区块链、比特币的原理还是很好理解的。我觉得得有个前提,前提是你已经理解了哈希算法、非对称加密、数字签名这些基本知识,也不复杂,我推荐刘欣的一篇文章,我觉得有这一篇文章就够了 - 一个故事讲完 HTTPS

先解释一下比特币和区块链的关系,区块链是比特币所用到的底层技术,用来实现比特币去中心、匿名、无法篡改等能力,而比特币是区块链技术的一种应用。

总觉得区块链技术和 Git 在实现上有很多相似之处,但很少看到对它们进行比较的讨论。(马上搜了一下 "区块链 git",在 google 首页结果中看到了三个比较的结果,倒也不是完全没有。)

Note 1

Note for 廖雪峰 - 数字货币与区块链原理

1 - 简介

数字货币:

用一句话概括,数字货币是基于数学加密原理构建的不可伪造的货币系统,而比特币是第一个基于数学加密原理构建的分布式数字货币系统。

  • 区块链 - 不可篡改原理
  • P2P 交易 - 零信任密码学支付原理
  • 挖矿 - 工作量证明原理
  • 支付 - 可编程货币原理

比特币的特点

  • 创建了无需信任中心的货币发行机制 (Decentralization / 去中心化)
  • 发行数量由程序决定,无法随意修改
  • 交易账本完全公开可追溯,不可篡改 (Blockchain / 区块链)
  • 密码学理论保证货币防伪造,防双花
  • 数字签名机制保证交易完整可信,不可抵赖和撤销...

比特币网络

  • P2P 网络,无中央节点
  • 钱包节点,把比特币交易发送到网络中
  • 矿工节点,负责把网络中的交易打包到区块链中,并赚取挖矿的费用和交易手续费

2 - 区块链不可篡改原理

由哈希算法保证。

区块链是由一个一个区块构成的有序链表,每一个区块都记录了一系列交易,并且,每个区块都指向前一个区块,从而形成一个链条。

每个区块由区块头和区块体组成。对区块体进行某种 hash 算法,最后得到的哈希值,存放在区块头的 "Merkle Hash" 字段中。

然后对区块头再进行 hash,得到的哈希值,就是这个区块的哈希值,它的值会存入在下一个区块的区块头的 "Prev Hash" 字段中。

因此,生个区块头中都有一个 "Prev Hash" 来指向上一个区块,从向形成了一条链,这条链就是区块链。

只要区块中有一个比特的修改,就会导致 hash 发生变化,从而导致链条断裂。

网络中的每一个节点都有整个区块链的完整副本,因此,想要修改整个网络的区块链,几乎是不可能的。

每一个区块的区块体中记录的就是交易,第一笔交易是矿工挖矿得到的奖励。在比特币中,大约每 10 分钟产生一个区块,一个区块的大小限制在 1MB,根据一笔交易的大小,一个区块中最多包含 2000 笔交易。

(另外,区块链的不可篡改性还取决于,必须存在很多个节点,如果节点过少,大部分被相同的人控制,很容易就超过 51% 了,那还是很容易被篡改)

3 - 去中心化 P2P 交易原理

由数字签名 (非对称加密) 保证。

使用数字签名时,每个人都可以自己生成一个秘钥对,这个秘钥对包含一个私钥和一个公钥,私钥被称为 Secret Key (或者 Private Key),私钥必须严格保密,不能泄漏给其他人,公钥被称为 Public Key,可以公开给任何人。

当私钥持有人,例如,小明希望对某个消息签名的时候,他可以用自己的私钥对消息进行签名,然后,把消息、签名和自己的公钥发送出去。

其他任何人都可以通过小明的公钥对这个签名进行验证,如果验证通过,可以肯定,该消息是小明发出的。

数字签名算法在电子商务、在线支付这些领域有非常重要的作用:

  • 首先,签名不可伪造,因为私钥只有签名人自己知道,所以其他人无法伪造签名。
  • 其次,消息不可篡改,如果原始消息被人篡改了,那么对签名进行验证将失败。
  • 最后,签名不可抵赖。如果对签名进行验证通过了,那么,该消息肯定是由签名人自己发出的,他不能抵赖自己曾经发过这一条消息。

数字签名算法

RSA / DSA / ECDSA ... 比特币用的是 ECDSA。

比特币的密钥对:私钥 256bit 整数,公钥 512bit 整数,通过私钥可以很容易推荐出公钥,所以不必保存公钥,但通过公钥无法反推私钥,只能暴力破解。

由于比特币账本是全网公开的,所以,任何人都可以根据公钥查询余额,但是,不知道持卡人是谁。这就是比特币的匿名特性。

比特币钱包

  • 本地钱包 - 把私钥保存在本地计算机硬盘上的钱包软件
  • 在线钱包 - 是把私钥委托给第三方在线服务商保存

由于私钥和公钥的位置太长,不方便表示,人们通过对它们进行 hash 后再做 base58 编码,生成更短的且大部分是英文字母的字符串,来替代显示私钥和公钥,比如这样一个转换后的私钥:5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ,这种称为私钥地址,又称为钱包导入地址 (WIF: Wallet Import Format)。

作为用户,可以生成任意数量的私钥-公钥对,公钥是接收别人转账的地址,而私钥是花费比特币的唯一手段,钱包程序可以帮助用户管理私钥-公钥对。

交易

每个区块都记录了至少一笔交易,一笔交易就是把一定金额的比特币从一个输入转移到一个输出。例如,小明把两个比特币转移给小红,这笔交易的输入是小明,输出就是小红。实际记录的是双方的公钥地址。

这一小节的细节讲得不是很清楚,先略过。

4 - 工作量证明的挖矿原理

在比特币的 P2P 网络中,有一类节点,它们时刻不停地进行计算,试图把新的交易打包成新的区块并附加到区块链上,这类节点就是矿工。因为每打包一个新的区块,打包该区块的矿工就可以获得一笔比特币作为奖励。所以,打包新区块就被称为挖矿。

工作量证明 - POW (Proof Of Work)

我简单总结一下挖矿的过程:首先,在上一个区块被挖出后,所有矿工节点开始准备下一个区块的挖取,它们先生成一个临时的区块,把最近的交易打包到这个临时区块体中,同时将挖矿得到的奖励放在交易的第一条 (输出地址是矿工的公钥),然后对区块体生成 Merkle Hash 值,放到区块头中,同时区块头中还有上一个区块的 Hash 值等其它信息,同时,区块头中还有一个叫 nonce 的字段,这个矿工节点要做的事情就是,不断地变换这个 nonce 值 (比如从 0 开始递增),每调整一次,重新计算区块头的 Hash 值,如果哪一次这个算出来的 Hash 值,正好符合网络给出来的要求,它的值小于某个给定的值,bingo! 这个区块就算是成了,挖出来了,这个区块被广播出去,其它矿工节点验证成功后,这个区块就会加到区块链上。其它矿工放弃当前的工作,转而进行下一个区块的挖掘。

共识算法

解决两个矿工节点同时找到了有效区块的问题。虽然短时间内,两个区块都有可能加到区块链上,这时会导致区块链分叉。但一段时间后,区块链会放弃更短的链,只使用更长的链,以保证只有一条链。准确的说,分叉后的部分,区块数先到达 6 的那条链会保留下来,其余抛弃。

5 - 可编程的支付原理

交易的核心。Got it! 精妙!

比特币的支付实际上并不是直接支付到对方的 Public Key,而是一个脚本,这个脚本的意思是:谁能够提供另外一个脚本,让这两个脚本能顺利执行通过,谁就能花掉这笔钱。

比特币交易的输出是一个锁定脚本,而下一个交易的输入是一个解锁脚本。必须提供一个解锁脚本,让锁定脚本正确运行,那么该输入有效,就可以花费该输出。

比特币脚本是一种基于栈结构的编程语言 (语法类似汇编... 汗),详略。

当小明给小红支付一笔比特币时,实际上小明创建了一个锁定脚本,该锁定脚本中引入了小红的公钥。要想通过解锁脚本花费该输出,只有持有对应私钥的小红才能创建正确的解锁脚本 (因为解锁脚本包含的签名只有小红的私钥才能创建),因此,小红事实上拥有了花费该输出的权利。

使用钱包软件创建的交易都是标准的支付脚本,但是,比特币的交易本质是成功执行解锁脚本和锁定脚本,所以,可以编写各种符合条件的脚本。

比如,有人创建了一个交易,它的锁定脚本像这样:

OP_HASH256
DATA 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000
OP_EQUAL

这有点像一个数学谜题。它的意思是说,谁能够提供一个数据,它的 hash256 等于 6fe28c...,谁就可以花费这笔输出。所以,解锁脚本实际上只需要提供一个正确的数据,就可以花费这笔输出。

比特币的脚本通过不同的指令还可以实现更灵活的功能。例如,多重签名可以让一笔交易只有在多数人同意的情况下才能够进行。

支付的本质

从比特币支付的脚本可以看出,比特币支付的本质是由程序触发的数字资产转移。这种支付方式无需信任中介的参与,可以在零信任的基础上完成数字资产的交易,这也是为什么数字货币又被称为可编程的货币。

由此催生出了智能合约:当一个预先编好的条件被触发时,智能合约可以自动执行相应的程序,自动完成数字资产的转移。保险、贷款等金融活动在将来都可以以智能合约的形式执行。智能合约以程序来替代传统的纸质文件条款,并由计算机强制执行,将具有更高的更低的信任成本和运营成本。

补充

比特币矿工的收益不仅来自挖矿后得到的奖励,还来自交易的手续费,矿工优先处理手费续高的交易,如果手续费太低,这笔交易可能迟迟得不到确认。

奖励最初设计 50 比特币,每 4 年减少,到 2140 年时,奖励将为 0,比特币的数量也将停止增加 (因为新增的比特币完全来自采矿奖励),之后,收益将完全来自交易的手续费...

Note 2

Note for 精通比特币

这篇教程写得很详细,解释了很多细节,感觉廖雪峰的文章基本是这篇教程的总结。

进一步搞清了之前疑惑的一些地方。

首先,虽然我们常说一笔交易至少要 10 分钟才能确认,但并不是说交易者就要在那死等 10 分钟。比如 A 去咖啡店买咖啡,付给咖啡店 0.1BTC,这笔交易是马上发生的,且无法撤消,A 不用在那等 10 分钟后才能离开。只不过,咖啡店确实无法马上消费这 0.1BTC,这笔交易必须被打包到区块上后,咖啡店才能消费它。这是正常的,正如现实生活中,通过银行转账,也是需要一个确认周期的。

当一笔交易发生时,这笔交易会发送到一些节点 (应该是矿工节点) 的交易池中,交易池中存放的就是即将打包到区块中的交易。矿工们要准备挖取下一下区块时,就从这些交易池中按优先级取选一些交易,打包到临时区块中,当区块真正生成时,这笔交易才真正记录到区块链上了,然后这笔交易被锁定,只有交易的输出者 (这里指咖啡店) 必须提供用私钥加密的数据才能解锁这笔交易。

这笔锁定的交易,只有咖啡店想消费它时,才需要去解锁它,否则它无须被解锁。

当一个人想用 BTC 进行消费时,交易的输入并不是本人的余额,区块链账本上没有余额的概念,输入是上一笔 (或多笔) 别人转账给你的交易,这些交易此时处于锁定中,你正好用你的私钥去解锁它们。

当然,用户不用知道这些细节,这些底层细节都由钱包帮你完成了。

另外,关于交易手续费的问题,并不是说如果你交易不给手续费,交易就会一直无法上区块链,只是会比较晚上。当你的交易没有手续费时,这笔交易在交易池是会呆一段时间,但随着时间增长,它的优先级会随着时间增长而提升,总有一天,它的优先级会超过有手续费的交易。每次矿工打包交易时,区块体中总有一部分位置是留给这些没有手续费但在交易池中已经呆了很久的交易。

Note 3

看完上面一些文章后,这两篇基本就没有什么新内容了。

最后,一点感悟,站在纯技术的角度,当在阅读这些文档时,会觉得 wow,太妙了,这设计太牛叉了。但跳出这个圈子来看,浪费大量电力来计算 hash 挖矿,实在是 ridiculous! 难道就不能用这些计算量来做一些实际有意义的事情吗?比如把计算 hash 替换成完成某项实际有意义的任务?

results matching ""

    No results matching ""