区块链介绍
区块链是什么?
在开始了解区块链之前,我们应该先了解另一个概念————分布式。
分布式系统是要多个节点共同协作,对外表现为一个整体系统。
这听起来似乎并不难,一个单线程程序,如果跑在一台计算机上,结果是非常容易预测的,我们往往可以根据代码对运行的结果进行直接的推断。
刚开始上手编程语言的人总是会抱怨,多线程编程真难,即便是有经验的老手也不一定能够很好地解决多线程问题。
如果你需要运行多线程程序,此时恰好你没有设置相应的同步机制,你的多线程代码就会以一种未知的、难以预测的状态运行下去,以至于有时候结果都无法复现。
分布式的难度更甚,实际上分布式的问题是多线程的问题的升级版,分布式不仅有多线程的所有问题,还要考虑网络、不可靠节点、时钟漂移等问题
区块链实际上就是一项分布式系统的工程技术,区块链想要一组计算机网络,它们必须在不互相信任的情况下就共享数据达成一致。
关于分布式系统
我们知道,单线程扩展到多线程并不是量的变化而是质的变化,同样地,将单个计算机扩展为多台计算机并组成一个系统,难度也是会发生质变的。
CAP定理
1999年,计算机科学家Eric Brewer提出了CAP定理,简单来说,一个分布式系统最多只能满足以下三个条件中的两个:
- 一致性(C):所有服务器始终访问同一份最新的数据。
- 可用性(A):每次请求都能够得到一个不报错的响应,但是不保证获得的数据是最新的数据。
- 分区容错性(P):系统能在网络故障的时候,服务器被分为孤立的组,但是系统依旧可以运行。
2010年,耶鲁大学教授丹尼尔·阿巴迪提出PACELC理论,扩展了CAP定理。原有的CAP定理重写为PAC,ELC则代表“Else, choose between (low) latency and consistency”。在网络正常(没有分区)的情况下,须选择低延迟或一致性。
根据PACELC理论,分布式系统可分为四种不同的运作模式
- PA/EL: 相比数据一致性,优先选择可用性和低延迟
- PA/EC: 出现分区时选择可用性,无分区时选择一致性
- PC/EL: 出现分区时选择一致性,无分区时选择低延迟
- PC/EC: 任何时候,以保持数据一致性为优先
设计师可以自行设定数据库管理系统的运作模式。
例如,一个系统包含两份数据,可读写的主数据库和只读的副数据库。如果副数据库与主数据库同步,则系统属于EC。如果副数据库并异步,但允许读取,则系统属于EL。如果副数据库不适合设定为同步备份,设计师可停用读取功能,让用户只读取主数据库,此时系统为EC。
传统的系统通常选择一致性和分区容错性(CP系统),宁可系统无法使用,也不能让数据出错;而社交媒体平台通常选择可用性+分区容错性(AP系统),哪怕其他人看不见,也不影响你的内容发布。
必须保证在C和A之间做出选择
值得注意的是,虽然我们说CAP三个条件只能实现两个,但是就实际效果而言,分区相当于对通信的限时要求,系统如果不能在规定时限内达成数据一致性,就意味着发生了数据分区的情况,当P发生的时候,我们要在C和A之间做出选择。在没有出现分区的时候(没有P发生的时候),C和A都不需要被放弃。这三个条件不是互相对立的,而是在一定程度上是连续的,我们实际上是在这三个条件上进行一定的取舍。
所以CAP定理的核心讨论点在于,CAP 不是说三者永远对立,而是说明在网络分区这种不可避免的场景下,C 和 A 存在根本性的冲突,系统必须事先设计好取舍策略。
拜占庭将军问题
相比CAP探讨的问题而言,拜占庭将军问题更为复杂,CAP定理主要讨论的是出现网络分区也就是网络出现问题的时候,该采取什么样的策略,它默认所有的节点都是诚实的,可能会失败或者断开连接,但是不会欺骗对方,而拜占庭将军问题还要考虑系统中可能存在恶意节点这一情况。
假如一个分布式系统中存在恶意节点发布虚假信息,整个系统中的所有节点就难以达成一致。
计算机科学家 Leslie Lamport 在 1982 年提出的拜占庭将军问题,说明了这一挑战:
一组拜占庭将军分别各率领一支军队共同围困一座城市。为了简化问题,将各支军队的行动策略限定为进攻或撤离两种。因为部分军队进攻部分军队撤离可能会造成灾难性后果,因此各位将军必须通过投票来达成一致策略,即所有军队一起进攻或所有军队一起撤离。因为各位将军分处城市不同方向,他们只能通过信使互相联系。在投票过程中每位将军都将自己投票给进攻还是撤退的信息通过信使分别通知其他所有将军,这样一来每位将军根据自己的投票和其他所有将军送来的信息就可以知道共同的投票结果而决定行动策略。
系统的问题在于,可能将军中出现叛徒,他们不仅可能向较为糟糕的策略投票,还可能选择性地发送投票信息。假设有9位将军投票,其中1名叛徒。8名忠诚的将军中出现了4人投进攻,4人投撤离的情况。这时候叛徒可能故意给4名投进攻的将领送信表示投票进攻,而给4名投撤离的将领送信表示投撤离。这样一来在4名投进攻的将领看来,投票结果是5人投进攻,从而发起进攻;而在4名投撤离的将军看来则是5人投撤离。这样各支军队的一致协同就遭到了破坏。
由于将军之间需要通过信使通讯,叛变将军可能通过伪造信件来以其他将军的身份发送假投票。而即使在保证所有将军忠诚的情况下,也不能排除信使被敌人截杀,甚至被敌人间谍替换等情况。因此很难通过保证人员可靠性及通讯可靠性来解决问题。
上述的故事映射到计算机系统里,将军便成了计算机,而信差就是通信系统。虽然上述的问题涉及了电子化的决策支持与信息安全,却没办法单纯的用密码学与数字签名来解决。因为电路错误仍可能影响整个加密过程,这不是密码学与数字签名算法在解决的问题。因此计算机就有可能将错误的结果提交去,亦可能导致错误的决策。
这似乎是不可能的。几十年来,计算机科学家认为无法构建一个同时具备以下特性的系统:
-
拜占庭容错(即使有恶意参与者也能正常工作)
-
无许可(任何人都可以无需批准加入)
-
去中心化(没有中央权威)
拜占庭将军问题的解决办法
不过拜占庭将军问题并不是没有解决办法,也有一些计算机科学家提出来了拜占庭将军问题的解决问题方案,例如:把问题往下拆解,认为在“拜占庭将军”的问题可以在“军官与士官的问题”里解决,以降低将军问题的发生,但是我们不详细探讨这些科学家提出的办法。
假使那些忠诚(或是没有出错)的将军仍然能通过多数决定来决定他们的战略,便称达到了 拜占庭容错。在此,票都会有一个默认值,若消息(票)没有被收到,则使用此默认值来投票。
不过回归最简单的解决思路就是,不让叛徒想要达成的结果被通票通过,者需要:
要容忍 f 个叛徒,至少需要 3f + 1 个节点
这本质就是:
-
用数量优势压制恶意节点
-
通过多数投票过滤谎言
这虽然不能可靠地找出谁是叛徒,但是最终叛徒想要的并没有达成,即使叛徒对不同的将军说出了不同的结果,最终的投票依旧是忠诚的将军占据上风。
而这就是拜占庭容错机制的本质,拜占庭容错机制本质上是一种防御机制,而不是一种纠错机制,因此他的目的是在有叛徒的情况下依旧不影响最终的结果,骗子无法控制投票。
(不过依旧还是有找出叛徒的办法的,但是这些办法成本很高,而且不是特别完善,应对简单问题可以,但是对复杂问题还是效果有限,例如:证据驱动型惩罚(Slashing)。在区块链里:节点如果签了互相矛盾的消息,就可以被当场处罚(扣钱 / 踢出))
共识机制
刚才我们提到的办法,让节点数量为3f + 1 以此来对 f 以及 f 以下数量的叛徒进行防御,虽然这是一种数学上可行的 共识机制,但是这在工程上并不实用。
最关键的一点是,我们根本不知道 f 是多少,而且叛徒的数量也有可能是会发生变化的,叛徒数量最多为 f 只是一个外部假设,没人能保证你的总节点数够用。
假如节点之间要进行多轮通信,那还需要知道节点的身份信息,以及每个节点都发出了多少轮信号。
而且对于无许可的系统,攻击者可以随意创建无限的虚假身份,也就是说,他可以派出无数个叛徒,即使你的忠诚节点数量很多,攻击者依旧有可能击穿你的防御。
所以实际上,我们根本不会直接用增加忠诚节点这种办法来应对攻击。
POW(工作量证明)
那我们该如何解决这个问题呢?
思考一下,为什么有的人要铸造假币?
因为铸造假币可以用更低的成本换取更多的价值和回报,但是为什么现在几乎没有人尝试铸造假币呢?
原因很简单,因为现在造假的成本非常高,铸造假币的成本变得很高,一是现在的纸币采用了很好的制造技术,仿造一个逼真的纸币对于大多数人而言技术上就难以实现,二是因为,铸造假币是违法的,一旦被发现了,就要承担严重的法律后果,对于想要铸造假币的人来说,这样算来,这不是一个好的盈利手段。
同理,对于分布式系统来说,我们不能完全杜绝一些节点背叛,但是我们可以提高背叛的成本,让攻击者攻击的成本变得大于他们可能的获益,这样,系统的安全性就得到了保障。
所以我们不是验证身份,因为在无许可的系统,创建一个新的身份非常容易,我们转而验证一些难以被伪造的东西,例如:计算工作量或者质押的资金。
在一个POW系统里面,当你想做些什么之前,你应该承担一些不便宜的工作量(例如进行以此花销较大的计算)。
在技术实现上我们可以这这样做:
提供给你一个哈希值,例如比特币就是给你一个SHA256,因为使用巧妙的算法根据哈希值反推原始值是不可能的,所以你必须采用暴力破解的算法,当你找到了原始值,这就是你的计算工作量的证明。
而验证你的结果是是否正确是一个很简单的很便宜的事,只需要把你计算的结果放到哈希函数中,进行一次运算,得到哈希值,与原来的哈希值进行一次比对,这种计算量小到可以忽略。
所以你要想在这样一个系统里面发起攻击,每次攻击之前你都需要付出工作量,这样你的攻击就会变得昂贵,当他昂贵到超过了攻击本身带来的收益,你就不会再考虑攻击这回事了。
POS(权益证明)
POS比POW更加激进,他并不将你的工作量视作证明,而是直接和你的资金挂钩,参与者将加密货币代币作为抵押,参与者将加密货币代币锁定作为抵押,协议根据其权益随机选择验证者提议区块,被选中的验证者提议区块,其他验证者投票接受或拒绝,诚实行为会获得奖励;不诚实行为会导致“削减”,即部分质押的代币被没收或罚没。具体的惩罚因网络和违规程度而异。
所以在发起攻击之前,你得考虑一下,自己的钱包到底受不受得了。
区块链的三元悖论
如同CAP定理一样,区块链中也存在这种三元的关系,从本质上来说,这就是CAP定理在区块链语境下的形式。
区块链的三元悖论通常指这三个目标无法同时最大化:
-
去中心化(Decentralization):没有单点控制者,任何人都能参与共识。
-
安全性(Security):抗攻击、抗篡改、抗作恶(比如 51% 攻击、双花)。
-
可扩展性(Scalability):高 TPS、低延迟、低手续费。
这里:
-
去中心化 ≈ 强分区容错 + 开放参与
-
安全性 ≈ 强一致性
-
可扩展性 ≈ 高可用性 + 低延迟
根据CAP,从理论上就不可能完全解决这种矛盾,原因很简单:
-
全球开放网络 → 一定会有网络分区
-
无中心 → 无法快速强制共识
-
抗攻击 → 需要复杂验证
-
高吞吐 → 必然牺牲验证成本
所以依旧是选择策略游戏。比特币选择了安全性和去中心化,而不是可扩展性。像 Visa 这样的传统支付系统选择了可扩展性和安全性,而不是去中心化。当前的挑战是找到同时实现这三者的方法(做权衡,最优化)。
区块链依赖的密码学原语
共识机制解决了“谁来决定”的问题,但我们如何确保数据本身是可信的呢?
密码学原语指的是:构建复杂密码系统(如VPN、TLS、数字签名)的基础、原子化的数学构建模块,它们本身不处理具体业务逻辑,而是提供核心的加密、认证或密钥交换功能。
区块链依赖于三种关键的密码学工具,它们协同工作以创建一个不可篡改且可验证的系统。
哈希函数
哈希函数具体的介绍可以看看视频:https://www.bilibili.com/video/BV1W1utzZESe/
总的来说,哈希函数具有三个关键属性:
-
确定性: 相同的输入总是会产生相同的输出。
-
不可逆性: 该函数在一个方向上易于计算,但在反方向上计算几乎不可能。给定一个哈希值,你无法轻易找到原始输入,除非通过暴力破解或查找表。
-
雪崩效应: 输入的微小变化(例如将一个字母大写)会导致完全不同的输出哈希值。
这三个关键特性决定了:虽然从任何输入计算哈希值是很简单的,但逆向过程在计算上是不可能的。给定一个哈希值,你无法推断出原始输入是什么,因为对于一个安全的哈希函数来说,这将耗费非常长的时间。
在区块链中,哈希用于确保数据的完整性。每个区块都包含前一个区块的哈希值,从而形成一个不可破坏的链条。如果有人试图修改上周的一笔交易,他们会改变该区块的哈希值。由于下一个区块引用了旧的哈希值,这种修改会破坏链条。要修复这一点,他们需要重新计算每个后续区块的哈希值,同时网络还在不断添加新的区块,这几乎是一个不可能完成的追赶游戏。
数字签名
数字签名使用非对称加密技术,这种技术依赖于一种数学关系:在一个方向上计算很容易,但几乎不可能反向计算。当您创建数字签名时,您会生成两个数学相关的数字,称为私钥和公钥;私钥必须保密,而公钥可以自由共享。
-
私钥可用于为特定交易创建数字签名。
-
签名是您私钥和确切交易内容的唯一组合。
-
任何人都可以使用您的公钥验证签名只能由拥有相应私钥的人创建。
OK,现在的问题是,数字签名到底是如何实现的呢?
实际上,有的人总是把数字签名和哈希搞混,根据上面对数字签名的描述,一部分人就会认为所谓的公钥和私钥就是这样得到的————产生一个随机数,对这个随机数以及发布的内容进行哈希,得到公钥,认为随机数是私钥。
听起来好像满足:单向性、难反推、有“私钥参与”。
但实际上,这种做法根本不是数字签名,
它只是一个一次性数字指纹生成器。
因为数字签名的核心不是“你算出了一个复杂的值”,
而是:所有人都能验证,这个值只能由你生成。
假设你这样做:你生成一个随机数作为“私钥”,把它和消息一起做 Hash,把 Hash 结果发到网上。
对外界来说,他们不知道你的私钥,也无法从 Hash 反推出私钥,更无法判断这是不是你算出来的。
总的来说,任何人都无法验证“这是你签的”
这不具备身份认证能力,也不具备不可伪造性,自然不能称为“数字签名”。
我们以ECC为例,真正的数字签名是这样的:
首先根据算法得到公钥和私钥:公钥 = 私钥 · G。私钥是一个随机大整数,G 是椭圆曲线上的固定基点,“·” 是点乘运算
然后我们使用私钥签名:签名 = f(消息的Hash, 私钥)
而其他人验证则是:验证结果 = g(签名, 消息的Hash, 公钥)
在这个过程中确实也使用了哈希,但是哈希的作用是压缩信息,将一个可能很长的消息,压缩为一个固定长度的哈希值。
这里的关键在于————只有私钥能生成合法签名,任何人都能用公钥验证,但没人能从公钥反推私钥。
这正是非对称密码学的安全基础。
默克尔树
如何在包含数千笔交易的区块中验证特定交易的存在,而无需下载整个区块?
默克尔树以二叉树的形式组织数据,其中每个叶子代表一笔交易,每个父节点包含其两个子节点的哈希值。这种结构一直延续到树的顶部,最终形成一个代表整个数据集的根哈希值。
因此,要证明树中存在任何交易,您只需要该交易和“默克尔路径”:用于重建根的兄弟节点哈希值。这意味着对于包含一百万笔交易的树,您只需要大约 20 个哈希值即可证明包含性。
在区块链中,默克尔树使得仅凭几千字节的证明就能极其轻松地验证交易。安全性保证保持不变:如果默克尔路径验证正确,您可以在数学上确定该交易已包含在该区块中。
区块链的发展
通过以上的介绍,希望您大概已经能够理解区块链技术是什么,他是如何产生的,以及它产生的原因。
虽然区块链是一个比较新的技术,但是他和所有事物一眼都有一个发展的过程,最开始的区块链产物就是比特币(Bitcoin),让矿工去暴力搜索随机数,这是一种非常经典的POW系统。
比特币的这种暴力计算其实没有什么特别的意义,只是搜索花费的时间可以很好地用于衡量工作量,但是如果通过