写点什么

为什么比特币可以防篡改

2020 年 2 月 28 日

为什么比特币可以防篡改

比特币(Bitcoin)是一种加密货币,也是一种分布式的数字资产,中本聪发布比特币到今天已经过去了 10 多年时间1,一些读者可能接触过区块链技术,甚至投资过数字货币的资产。今天的区块链总市值已经达到了 2700 亿美金,比特币的市值也达到了 1700 亿2,然而比特币使用的底层技术其实非常简单,它只是将这些技术巧妙地组合起来。



图 1 - 比特币


如果我们对比特币等区块链技术稍有了解,就会发现它是一个设计巧妙的分布式数据库。作为在公网运行的分布式数据库,比特币和其它区块链网络都会面对网络中的恶意节点的攻击。因为比特币需要面对复杂的网络环境以及不可靠的节点,所以它在设计和实现上也做出了应对,我们可以看看它是如何组合现有的技术防止恶意节点对交易和账户数据进行篡改的。


比特币网络主要会通过以下两种技术保证用户签发的交易和历史上发生的交易不会被攻击者篡改:


  • 非对称加密可以保证攻击者无法伪造账户所有者的签名;

  • 共识算法可以保证网络中的历史交易不会被攻击者替换;


非对称加密

非对称加密算法3是目前广泛应用的加密技术,TLS 证书和电子签名等场景都使用了非对称的加密算法保证安全。非对称加密算法同时包含一个公钥(Public Key)和一个私钥(Secret Key),使用私钥加密的数据只能用公钥解密,而使用公钥解密的数据也只能用私钥解密。



图 2 - 非对称加密特性


比特币使用了非对称加密算法保证每一笔交易的安全,网络中的每一个账户(地址)都是一对秘钥中的公钥,账户的所有者会持有私钥,下面就是一对刚刚生成的比特币地址和私钥4


Go


Address:     13RTT8MsbAj7o4zL7w4DNNuuwhgGgHqLnKPrivate Key: 469d998dd4db3dfdd411fa56574e52b6be318f993ca696cc5c683c45e8e147eb
复制代码


需要注意的是,使用网站生成比特币地址和私钥是极其危险的做法,我们并不清楚网站是否会存储私钥,所以建议使用比特币的客户端生成公私钥对。


任何人通过上面的地址 13RTT8MsbAj7o4zL7w4DNNuuwhgGgHqLnK 都可以向该账号转账;账号的持有者也可以使用私钥签名交易向其他地址转账,当我们想要向比特币网络中提交一笔新的交易时,需要先构建一个如下所示的交易结构:


JSON


{   "txid":"5be7a9e47f56c98e5297a44df52da0475f448ece98bb51489103cdf70653092f",   "hash":"5be7a9e47f56c98e5297a44df52da0475f448ece98bb51489103cdf70653092f",   "version":1,   "size":224,   "vsize":224,   "locktime":0,   "vin": [...],   "vout": [...],   "hex":"0100000001a90b4101e6cbb75e1ff885b6358264627581e9f96db9ae609acec98d72422067000000006b483045022100c42c89eb2b10aeefe27caea63f562837b20290f0a095bda39bec37f2651af56b02204ee4260e81e31947d9297e7e9e027a231f5a7ae5e21015aabfdbdb9c6bbcc76e0121025e6e9ba5111117d49cfca477b9a0a5fba1dfcd18ef91724bc963f709c52128c4ffffffff02a037a0000000000017a91477df4f8c95e3d35a414d7946362460d3844c2c3187e6f6030b000000001976a914aba7915d5964406e8a02c3202f1f8a4a63e95c1388ac00000000",   "blockhash":"0000000000000000000c23ca00756364067ce5e815deb5982969df476bfc0b5c",   "confirmations":5,   "time":1521981077,   "blocktime":1521981077}
复制代码


接下来,我们可以使用持有的私钥对整个交易中的全部字段进行签名,然后将签名与交易打包并发送到网络中等待比特币网络的确认就可以了。


在比特币的所有地址中,35hK24tcLEWcgNA4JxpvbkNkoAcDGqQPsP 地址中目前持有 250,000 多个 Bitcoin5,目前的市值大概为 20 亿美元。在只知道地址的情况下,我们来算一下获取该地址对应的私钥需要多长时间。比特币的私钥总共有 256 位,即 22562256 中可能性:


115792089237316195423570985008687907853269984665640564039457584007913129639936115792089237316195423570985008687907853269984665640564039457584007913129639936


目前我们没有较为快捷的破解手段,只能使用暴力破解计算私钥。假设我们使用 IBM 在 2018 年推出的超级计算机 Summit6,它能每秒能做 1.4∗10171.4∗1017 次浮点数计算,假设该计算机可以每秒计算相同次数的公私钥对(计算公私钥对远比一次浮点数计算复杂),想要找到存放 20 亿美元资产的地址对应的私钥需要如下所示的时间:


1.15∗1077365∗86400∗1.4∗1017=2.9∗1052 年 1.15∗1077365∗86400∗1.4∗1017=2.9∗1052 年


我们整个宇宙的存在时间也只是破解该私钥时间的几十亿分之一,所以在目前的计算能力没有革命性突破的前提下,想要通过暴力破解的方式获取公钥对应的私钥只有理论上的可能性,在实践中是完全不可能的7


共识算法

MySQL 等数据库以行为单位存储数据,而比特币这个分布式数据库中存储的基本单位是区块,区块通过哈希指针连接就会构成一颗树,如下图所示,图中绿色的最长链就是网络的主链。



图 3 - 区块链和主链


如何让网络中的所有节点对下一个区块中的内容达成共识是比特币需要解决的关键问题,只有让节点对数据达成一致才会保证过去的交易不会被篡改,但是作为在公网运行的分布式数据库,它面对的场景非常复杂,需要解决拜占庭将军问题下的分布式一致性问题。


拜占庭将军问题是 Leslie Lamport 在 The Byzantine Generals Problem 论文中提出的分布式领域的容错问题,它是分布式领域中最复杂、最严格的容错模型8。在该模型下,系统不会对集群中的节点做任何的限制,它们可以向其他节点发送随机数据、错误数据,也可以选择不响应其他节点的请求,这些无法预测的行为使得容错这一问题变得更加复杂。


拜占庭将军问题描述了一个如下的场景,有一组将军分别指挥一部分军队,每一个将军都不知道其它将军是否是可靠的,也不知道其他将军传递的信息是否可靠,但是它们需要通过投票选择是否要进攻或者撤退:



图 4 - 拜占庭将军问题


区块链技术使用 共识算法 和激励让多个节点在拜占庭将军场景下实现分布式一致性。比特币使用如下的规则让多个节点实现分布式一致性:


  1. 引入工作量证明 — 让节点在提交新的区块之前计算满足特定条件的哈希,取代传统分布式一致性算法中,一人一票(或者一节点一票)的设定;

  2. 引入最长链是主链的设定 — 只有主链上的交易才被认为是合法交易;

  3. 引入激励 — 提交区块的节点可以获得比特币奖励;


通过以上的规则,各个节点会在最长的链上计算哈希,努力提交合法的区块。然而一旦节点中有人掌握了 51% 以上的计算能力,它能通过强大的算力改变区块链的历史。因为区块具有连续性,所以前一个区块的改变会使后一个区块计算的哈希失效,如图 4 所示,如果攻击者需要改变主链中的倒数第三个黄色区块,它需要连续构建四个区块才能完成对历史的篡改,其他的节点才会在这条更长的链上继续计算:



图 4 - 51% 攻击


使用如下所示的代码可以计算在无限长的时间中,攻击者持有 51% 算力时,改写历史 0 ~ 9 个区块的概率9


C


#include <math.h>#include <stdio.h>
double attackerSuccessProbability(double q, int z) { double p = 1.0 - q; double lambda = z * (q / p); double sum = 1.0; int i, k; for (k = 0; k <= z; k++) { double poisson = exp(-lambda); for (i = 1; i <= k; i++) poisson *= lambda / i; sum -= poisson * (1 - pow(q / p, z - k)); } return sum;}
int main() { for (int i = 0; i < 10; i++) { printf("z=%d, p=%f\n", i, attackerSuccessProbability(0.51, i)); } return 0;}
复制代码


通过上述的计算我们会发现,在无限长的时间中,占有全网算力的节点能够发起 51% 攻击修改历史的概率是 100%;但是在有限长的时间中,因为比特币中的算力是相对动态的,比特币网络的节点也在避免出现单节点占有 51% 以上算力的情况,所以想要篡改比特币的历史还是比较困难的,不过在一些小众的、算力没有保证的一些区块链网络中,51% 攻击还是极其常见的10


防范 51% 攻击方法也很简单,在多数的区块链网络中,刚刚加入区块链网络中的交易都是未确认的,只要这些区块后面追加了数量足够的区块,区块中的交易才会被确认。比特币中的交易确认数就是 6 个,而比特币平均 10 分钟生成一个块,所以一次交易的确认时间大概为 60 分钟,这也是为了保证安全性不得不做出的牺牲。不过,这种增加确认数的做法也不能保证 100% 的安全,我们也只能在不影响用户体验的情况下,尽可能增加攻击者的成本。


总结

研究比特币这样的区块链技术还是非常有趣的,作为一个分布式的数据库,它也会遇到分布式系统经常会遇到的问题,例如节点不可靠等问题;同时作为一个金融系统和账本,它也会面对更加复杂的交易确认和验证场景。比特币网络的设计非常有趣,它是技术和金融两个交叉领域结合后的产物,非常值得我们花时间研究背后的原理。


比特币并不能 100% 防止交易和数据的篡改,文中提到的两种技术都只能从一定概率上保证安全,而降低攻击者成功的可能性也是安全领域需要面对的永恒问题。我们可以换一个更严谨的方式阐述今天的问题 — 比特币使用了哪些技术来增加攻击者的成本、降低交易被篡改的概率:


  • 比特币使用了非对称加密算法,保证攻击者在有限时间内无法伪造账户所有者的签名;

  • 比特币使用了工作量证明的共识算法并引入了记账的激励,保证网络中的历史交易不会被攻击者快速替换;


通过上述的两种方式,比特币才能保证历史的交易不会被篡改和所有账户中资金的安全。到最后,我们还是来看一些比较开放的相关问题,有兴趣的读者可以仔细思考一下下面的问题:


  • 你对比特币的未来是怎么看的?

  • 如果要对比特币发起一次 51% 攻击篡改交易要花费多少成本?


本文转载自 Draveness 技术网站。


原文链接:https://draveness.me/whys-the-design-bitcoin-database


2020 年 2 月 28 日 17:26131

评论

发布
暂无评论
发现更多内容

【LeetCode】重塑矩阵Java题解

HQ数字卡

算法 LeetCode 2月春节不断更

C语言实用第三方库Melon开箱即用之多线程模型

码哥比特

c c++ Linux 后端 框架

C语言第三方库Melon开箱即用之词法分析器使用

码哥比特

c c++ Linux 后端 框架

1.开篇(听说你还在艰难的啃react源码)

全栈潇晨

React React Hooks react源码

2.react心智模型(来来来,让大脑有react思维吧)

全栈潇晨

React React Hooks react源码

【STM32】PWM 输出 (标准库)

AXYZdong

硬件 stm32 2月春节不断更

IDEA插件:快速删除Java代码中的注释

xiaoxi666

代码注释 Java 8 JavaParser

今日笔记

Nydia

ElasticSearch.03 - 基本原理

insight

elasticsearch 2月春节不断更

第一次异地过年有感

石君

思考 情感

微信红包封面,2021年为啥突然火了?

架构精进之路

春节 微信红包封面 商业洞察

写公号大半年,看看我都收获了些啥

架构精进之路

技术 总结 微信公众号 成长笔记

这是我的第一次JavaScript初级技巧

魔王哪吒

JavaScript 学习 程序员 前端 2月春节不断更

翻译:《实用的Python编程》01_05_Lists

codists

人工智能 后端 python 爬虫 列表 数据结构与算法

第四章作业-编写一个用例文档

秦挺

字幕组时代落幕,翻译的未来可能是?

字节跳动技术团队

【函数计算实践】nodejs初探示例——本地mac环境

程序员架构进阶

架构 nodejs 函数计算 七日更 2月春节不断更

开发利器——C语言必备实用第三方库

码哥比特

c c++ Linux 后端 框架

揭秘登上2021春晚舞台的黑科技-XR技术

架构精进之路

黑科技 vr 春晚 XR MR

13. 如果自己写的 Python 程序出错了,怎么办?

梦想橡皮擦

python 爬虫 2月春节不断更

给hugo博客添加评论功能

LanLiang

Hugo 静态博客 utterances

春节快过腻了?不妨关心下太空探索

脑极体

gradle中的增量构建

程序那些事

maven Gradle 程序那些事 构建工具

Elasticsearch mapping 复杂数据类型

escray

elastic 七日更 死磕Elasticsearch 60天通过Elastic认证考试 2月春节不断更

1480. 一维数组的动态和

小马哥

算法 七日更

程序员成长第五篇:如何选择城市工作?

石云升

程序员成长 2月春节不断更 选择城市

LeetCode题解:1091. 二进制矩阵中的最短路径,BFS,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

【LeetCode】数组拆分Java题解

HQ数字卡

算法 LeetCode 2月春节不断更

日记 2021年2月17日(周三)

Changing Lin

2月春节不断更

EternalWallet为您提供快速、便捷、低价的国际汇款服务

Geek_c610c0

3.Fiber(我是在内存中的dom)

全栈潇晨

React React Hooks react源码

「中国技术开放日·长沙站」现场直播

「中国技术开放日·长沙站」现场直播

为什么比特币可以防篡改-InfoQ