读书导读 · CC BY-SA 4.0
《精通比特币:开放区块链编程》全书摘要与逐章导读
引文按 CC BY-SA 4.0 使用;本页文字也按同一协议授权,引文译文属于改编作品。免费阅读原书。
《精通比特币:开放区块链编程》讲了什么AI 辅助
比特币不只是货币,而是分层搭起的信任网络
一个问题:当没有人可信时,钱怎么能运转?本书的回答是,比特币最好被读作一个去中心化的信任网络,而不是一种货币,它的各章由内而外地搭建起这个网络。它从密钥、地址和“所有权不过是一把密钥”的主张开始;转向交易,那里币只作为未花费输出存在,由签名的引用串成链;然后是钱包,一个备份的种子确定性地重新生成整棵密钥树;然后是 Script 和签名,花费条件保持无状态、有界且可统一验证;然后是扁平的点对点网络、哈希链接的链和默克尔证明;然后是挖矿、难度和涌现的共识,诚实的验证在那里不过是最便宜的策略;最后是安全实践和诸如支付通道之类的第二层,它们组合现有的保证,而不是改变规则。每一层都由同一个检验来证明合理:一个普通参与者自己的软件,能不能不信任任何人就检查它?因此,最终性是经济性的、概率性的,而不是绝对的。
一则讲透全书的寓言AI 辅助
用一个故事装下全书最核心的想法,并老实交代故事在哪里失真。
一个记账人死了,于是整个山谷改成人人抄账
从前,有个山谷,住着一千个磨坊主,没有镇长。谷物的债务一向由老瓦罗记录,他保管着唯一的一本账簿,每记一行收一枚硬币,嫌小额债务不值他的墨水,一概拒记。瓦罗死后,磨坊主们慌了:谁来说谁欠了谁什么?一个叫爱丽丝的安静女人,提出了一个听上去像疯话的主意。让每个磨坊主都保管整本账簿。不要求任何人去相信任何人。每笔债务不写成“爱丽丝有三袋”,而写成“这一袋,去年秋天波交给爱丽丝的那一袋,现在转给赛勒斯”——一串指回头的链条,一直指回大家都亲眼见过的第一次收成,每一次指向都用发送者自己的印戒封印,而这印戒是让一袋谷物属于她的唯一凭据。丢了戒指,就丢了谷物;山谷里没有人能再发给你一枚。至于决定下一页由谁来写,没有人投票,因为瓦罗的侄子们已经证明,一个人可以顶十个名字。相反,每个想写一页的磨坊主,必须先磨一座糠秕山,才能找到一粒黑谷——找起来艰苦,对着光让任何人检查却一瞬间就行——而他写的那一页,只有在其中每一行也都被别人自己的账簿所接受时,才能让他从公共粮仓里赚得新谷。侄子们试过了。他们不磨糠,只会嚷得更大声;山谷只是继续读着自己的账簿,他们的那些页就这么落了空。有个侄子改而试图从三页之前抹掉一笔买卖,却发现他得比整个山谷磨一座山更快地重新磨三座山——而他在这段时间里本可以老老实实赚到的新谷,比他想要抹掉的那笔买卖还值钱。于是他像所有人一样,老实地磨起了糠。低地来的访客们太忙,没法保管整本账簿,学会了只索要一小串封印标记,证明他们的那袋谷物被写在某一页上,并在宣布买卖了结之前,数一数在它上面又磨了多少座山。他们中有些人从没意识到,他们其实又在相信这个山谷了,多少有一点。
故事里的每样东西代表什么
| 故事里 | 书里 |
|---|---|
| 一千个磨坊主,各自保管整本账簿,没有镇长 | 扁平的点对点拓扑,以及作为信任之根的全节点验证——去中心化的控制,每个参与者自己的软件检查每一个环节 |
| 瓦罗,每行收一枚硬币,拒记小额债务 | 由第三方居中的基于信任的调解,把小额支付定价到不复存在 |
| 写成“这一袋,波交给爱丽丝的那一袋”,而不是“爱丽丝有三袋” | 没有币,只有未花费输出,通过对此前特定输出的签名引用串成链,一路回溯到创世区块 |
| 唯一让一袋谷物归你所有的印戒,丢了没有替换 | 密钥作为持有者所有权——私钥就是所有权的全部,协议对丢失或泄露没有任何补救 |
| 磨一座糠秕山只为找一粒黑谷,找起来艰苦,检查起来瞬间 | 挖矿与工作量证明:共识靠计算成本买来,而不是靠身份清点 |
| 那个顶着十个名字、嚷得更大声,页面却落了空的侄子 | 为什么基于身份的投票被拒绝——任何能分配许多地址的人都能颠覆它,而涌现的共识遵循的是工作量最大的链 |
| 只有页面里的每一行都能被别人的账簿所接受,才付新谷 | 区块补贴以只包含有效交易为条件,所以诚实的挖矿不需要警察 |
| 比整个山谷磨一座山更快地重新磨三座山,试图这样做反而损失了诚实的收入 | 确认深度与重组风险:最终性是经济性的、概率性的,随深度指数衰减,因为发行比逆转更划算 |
寓言在哪里失真
寓言在山谷的共识看起来像一个既成事实、而不是一个没有保证的假设之处发生了扭曲。它容纳不了本书自己的那些张力:基于成本的共识只有在算力保持分散时,才能抵抗伪造身份,而设计中没有任何东西保证这一点;以及假定攻击者看重的是以他想要抹黑的那个山谷计价的谷物。它也承载不了让验证有界而统一的机制——一个无状态、非图灵完备的 Script,输出脚本陈述条件,输入脚本提供满足条件的数据;只有在承诺恰好正确的字段时才可靠的签名;哈希脚本;让已签名交易保持有效的软分叉门控;每 2016 个区块重新调整一次的难度;对照最近十一个区块的中位数来读取的时间锁;基于种子的确定性密钥树;或者把这些保证组合起来、却依赖基础层不提供的警觉性的支付通道。而且磨坊主们诚实的阅读,掩盖了寓言自己的最后一句:低地人的捷径悄悄重新引入了山谷当初为废除它而建立的信任,而这条捷径在何处变得不可接受,书留着没有定论。
《精通比特币:开放区块链编程》的核心论点
全书捍卫的 10 个论点,按论证需要的顺序排列。
- 比特币最好被理解为一个去中心化的信任网络,而不是数字货币,它扁平的点对点拓扑是去中心化控制的基础,而不是实现上的偶然。
“大自然表明,去中心化的系统可以很有韧性,可以产生涌现的复杂性和惊人的精巧,而不需要中央权威、等级制度或复杂的部件。”
“Nature demonstrates that decentralized systems can be resilient and can produce emergent complexity and incredible sophistication without the need for a central authority, hierarchy, or complex parts.”
Preface › Why Are There Bugs on the Cover?查看原文 → - 不需要可信的第三方,因为每个参与者自己的软件都能从创世区块起,独立验证系统的每个环节——而对确信钱仍然可以花出去的需要,正是运行这个软件值得的原因。
- 挖矿通过接管发行和清算两件事,取代了中央银行,但把它当作造币,就混淆了激励与目的,而目的是去中心化的验证。
- 诚实的挖矿不需要警察,因为领取奖励以只包含有效交易为条件,而且发行新币比逆转自己的支付更划算。
- 交易的最终性是经济性的、概率性的,而不是绝对的:改写历史需要在交易之上的每个区块上都挖得过别人,所以攻击者的机会随深度呈指数衰减,几次确认就足够了。
- 共识应当靠计算成本买来,而不是靠身份清点,因为基于信任的居中调解会把小额支付定价到不复存在,而基于身份的投票,任何能分配许多地址的人都能颠覆它。
- 没有币,只有交易所隐含的价值,所以所有权是一条指向先前特定输出的签名引用的可验证链条,而转移是被数据说服的一次登记簿更新,而不是持有者凭证的交接。
- 因为密钥本身就构成所有权,钱包和应用的安全,必须以熵的质量、基于种子的确定性备份,以及分布在用户手中的保管来评判,而集中式的托管设计,放弃了比特币的安全优势。
- 验证必须保持有界、统一并向后兼容:Script 有意无状态且非图灵完备,签名只有在承诺恰好正确的数据时才可靠,而新的共识规则必须有门控,使已签名的交易保持有效。
- 比特币通过组合它现有的保证并转移成本——哈希脚本、链下通道、对稀缺区块空间的手续费拍卖——而不是通过改变共识规则,来增长能力。
逐章导读
每一章都在本页:论证怎样展开、关键论点、常见误读和核心概念。从目录里选一章。
第 1 章:简介
共识规则和工作量证明如何共同解决双花问题?
第 1 章是怎样展开的AI 辅助
开篇。 本章一开始,就把比特币剥到它实际的样子:一种纯粹虚拟的货币,哪里都没有币这个对象,无论是实体的还是数字的。价值只存在于把它从花费者转给接收者的交易之内,而转移者是用所有者的密钥产生的一个签名——所以所有权被简化为持有能签名的那把密钥。这个定义也是一种挑衅,因为它立刻提出了开篇其余部分必须回答的问题:如果没有对象,也没有发行者,谁来为这些比特担保?作者的回答是挖矿。任何有算力的人都可以对最近的交易反复处理一项困难的任务;大约每十分钟,有一位参与者成功,锁定之前的交易,并收取新创造的币,外加附在这些交易上的手续费。发行和清算——中央银行会掌握的两项工作——作为这场竞争的副产品自然而然地产生,而协议会重新调整任务的难度,使十分钟的节奏平均而言得以保持。
展开。 从这个机制出发,本章推出它的第一个后果,追踪的是钱而不是信任。奖励计划每四年释放尚未发行部分的一半,所以每一轮支付得都比前一轮少。累计总量不断攀升,但收敛于一个略低于 2100 万的天花板,而不会越过它;作者预测大约在 1411200 号区块左右,约 2035 年,流通中将有大约 99% 的全部币,并小心地指出,这是从协议规则中读出来的,而不是在世界上测量到的。“长期通缩”的刻画就是在这里挣得的——不是作为经济学观点被断言,而是作为已经写进发行代码的算术被展示出来。
转折。 从内部解释完系统之后,本章转向站在系统之外的读者,语域从机制转为实用建议。作者论证说,入门并不要求用卡购买:你可以从已经持有一些的朋友那里买,通过出售商品或服务来赚取,把现金塞进比特币 ATM,或者经由与银行账户相连的交易所。这一点是针对即时刷卡购买的摩擦而提出的,那种购买要求验证身份——这也是许多人把交易所账户与钱包保持距离的同一个原因。价格得到了平行的处理和平行的纠正:没有人定价。每个交易场所根据它自己最近一笔交易推导出报价,报价每秒变动许多次,而一个宽泛的单一数字之所以存在,只是因为某个定价服务把几个市场汇总成了成交量加权平均数。本章解释这个机制,却不声称测量市场深度,这让公布出来的“比特币价格”保持在它恰当的位置上:一个近似,而不是一个权威。
收尾。 本章落在一个悄悄为最后的区分搭台的演示案例上。乔扫描爱丽丝的二维码,发送 0.001 BTC;签名后的支付在节点之间逐个中继,几秒钟内就抵达大多数连接良好的对等节点,几乎立刻出现在她的钱包里。然而钱包把它标为未确认,因为什么都还没写下来。只有当矿工把它打包进一个区块,它才算清算完毕,变得难以撤销。快速传播和不可逆的结算是两个不同的事件,而这个间隔就是本章收尾的动作:它点出了读者尚未被展示的东西,并交接给下一章要讲的交易机制。
关键论点,以及支撑它们的原文
比特币是纯粹虚拟的——哪里都没有币这个对象,无论是实体的还是数字的。
作者的推理是,价值只存在于把它从花费者转给接收者的交易之内,而转移者是用所有者的密钥做出的一个签名。所有权因此等于持有能签名的那把密钥,而不是拥有一个东西——这引出了本章的问题:这样的比特,在没有权威的情况下如何能被信任。
“与传统货币不同,比特币货币是完全虚拟的。没有实体硬币,甚至没有单个的数字硬币。”
“Unlike traditional currencies, the bitcoin currency is entirely virtual. There are no physical coins or even individual digital coins.”
Introduction查看原文 →
挖矿接管了中央银行会做的事,所以不需要中央银行。
挖矿对任何有算力的人开放,大约每十分钟,有一位矿工为过去的交易增加安全性,并以新创造的币外加近期交易的手续费获得报酬。发行和清算因此都由普通参与者完成,回答了开篇关于权威的问题。
“比特币网络中的任何参与者,都可以作为矿工运作,用他们的计算设备来帮助保护交易。”
“Any participant in the Bitcoin network may operate as a miner, using their computing devices to help secure transactions.”
Introduction查看原文 →
因为发行按固定计划不断缩减,总供应量恰好停在 2100 万之前,这种货币在长期是通缩的。
顺着挖矿的支付方式,每四年释放剩余部分的一半,预计大约在 1411200 号区块左右,约 2035 年,约 99% 的币会进入流通。作者指出,这是从协议规则推导出来的预测,而不是观测到的测量值。
“由于比特币的发行速率递减,从长远看,比特币货币是通缩的。”
“Due to Bitcoin’s diminishing rate of issuance, over the long term, the Bitcoin currency is deflationary.”
Introduction查看原文 →
另外 3 个论点
新手入门不必用卡购买;耐心加一点创意,就能打开好几条路。
作者列出了具体的替代办法:从已经持有一些的朋友那里买,通过出售商品或服务来赚取,使用接受现金的比特币 ATM,或者经由与银行账户相连的交易所。这一点是针对即时刷卡购买需要验证身份的麻烦而提出的——这也是许多人把交易所账户与钱包分开的同一个原因。
“不过,只要有一点耐心和创造性的思考,你就不需要这样做了。”
“With a bit of patience and creative thinking, however, you won’t need to.”
Introduction › Getting Your First Bitcoin查看原文 →
没有人给比特币定价;是各个市场之间的交易在定价。
每个市场根据它自己最近一笔交易推导出价格,所以报价每秒变动许多次;定价服务必须汇总几个市场,并计算成交量加权平均数,才能发布一个宽泛的汇率。作者没有给出关于市场深度的数字,所以这是在解释机制,而不是在度量它。
“简短的回答是,价格由市场决定。”
“The short answer is that the price is set by markets.”
Introduction › Finding the Current Price of Bitcoin查看原文 →
迅速到达网络,不等于已经结算。
在演示案例中,乔的 0.001 BTC 在几秒钟内到达大多数连接良好的节点,并出现在爱丽丝的钱包里,但在某个区块包含它之前,它显示为未确认。快速中继和不可逆的清算是两个不同的事件——本章靠这一点来交接给下一章的交易机制。
“这意味着这笔交易已经传播到了网络上,但尚未记录到比特币的交易日志中,即所谓的区块链。”
“This means that the transaction has been propagated to the network but has not yet been recorded in the Bitcoin transaction journal, known as the blockchain.”
Introduction › Sending and Receiving Bitcoin查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
挖矿取代中央银行
任何参与者都可以把算力花在一项针对最近交易的反复任务上;平均每十分钟有一位成功,锁定过去的交易,并收取新创造的币外加近期的手续费。所以,发行和清算作为竞争的副产品发生,而协议会重新调整任务的难度,使十分钟的节奏平均而言得以保持。
机制 2
递减的发行限定了供应
奖励计划每四年发放尚未发行的币的一半,所以每一轮增加的都比上一轮少。累计总量不断攀升,但收敛于一个略低于 2100 万的天花板,而不会越过它,这就是作者为什么称这种货币在长期是通缩的。
机制 3
传播不等于结算
一笔签名后的支付在节点之间逐个中继,几秒钟内就出现在收款人的钱包里,但什么都还没写下来。只有当矿工把它打包进一个区块,它才算清算完毕,变得难以撤销,这就是钱包在这期间把它标为未确认的原因。
常见误读
拥有比特币,意味着我的钱包里躺着某个我可以复制或交出去的数字币或文件。
存在的是一份转移的记录;你能花的数额,隐含在把价值转给你的那些交易之中,而你的钱包持有授权下一次转移的密钥。对这把签名密钥的控制就是所有权的全部——不过持有密钥证明的是花费的能力,而不是法律上的所有权。
“与传统货币不同,比特币货币是完全虚拟的。没有实体硬币,甚至没有单个的数字硬币。”
“Unlike traditional currencies, the bitcoin currency is entirely virtual. There are no physical coins or even individual digital coins.”
Introduction查看原文 →
任何时刻都只有一个官方的比特币价格,所以我看到的任何报价就是价格。
每个交易场所根据它自己那里最新的一笔交易算出自己的价格,这些报价每秒变动许多次。一个宽泛的单一数字,只来自某个按成交量加权平均几个市场的服务,所以它是对市场的近似,而不是权威的汇率。
“简短的回答是,价格由市场决定。”
“The short answer is that the price is set by markets.”
Introduction › Finding the Current Price of Bitcoin查看原文 →
第 1 章的核心概念
- 小写 bitcoin 对大写 Bitcoin
- 小写 b 指货币单位;大写 B 指系统。
- 适用处: 是本书的命名约定,不是协议规则。
- 密钥即所有权
- 币只存在于交易之内;持有签名密钥就是所有权的全部。
- 适用处: 持有密钥证明的是花费的权限,而不是法律上的所有权。
- 挖矿
- 对最近的交易反复处理一项计算任务,以保护它们,并赚取新币外加手续费。
- 适用处: 对任何参与者开放;奖励平均每 10 分钟左右到来一次。
- 难度调整
- 协议重新调整任务的难度,使成功仍然大约每十分钟出现一次。
- 适用处: 平均而言成立,对任何单个区间不成立。
- 浮动汇率
- 比特币的价格不由任何人固定;它随各个交易市场的供求而变动。
- 适用处: 每个市场根据它自己最新的一笔交易算出自己的价格;一个宽泛的汇率需要跨市场汇总。
- 确认
- 一笔交易只有被写进区块链上的一个区块之后才算结算完毕,大约每十分钟一次。
- 适用处: 在节点之间传播只需几秒钟,与确认不是一回事。
另外 1 个概念
- 地址与身份的关联
- 一旦一个地址与真实身份绑定,相关的交易,甚至更早的,都变得可以追踪。
- 适用处: 主要适用于比特币与受监管系统(比如货币交易所)接触的地方。
第 1 章划线与批注AI 陪读
“比特币可以说是互联网的完美货币形态,因为它快速、安全、无国界”
“Bitcoin is arguably the perfect form of money for the internet because it is fast, secure, and borderless”
查看原文 →“可以说”在这里承担了很多活。三者中最站不住脚的是“快速”——十分钟的区块和手续费市场就在这本书的后面。
“币隐含在把价值从花费者转给接收者的交易之中”
“The coins are implied in transactions that transfer value from spender to receiver”
查看原文 →到目前为止最有力的一句话。没有币,只有一份转移的账簿——所有权是语法,而不是对象。
“拥有能签署交易的密钥,是花费比特币的唯一前提”
“Possession of the key that can sign a transaction is the only prerequisite to spending bitcoin”
查看原文 →被写成赋权,但平淡地读:占有就是所有权,所以盗窃与花费无法区分。书将花几百页来偿付这笔账。
另外 17 条批注
“一个比特币矿工可以为过去的交易增加安全性”
“one Bitcoin miner can add security to past transactions”
查看原文 →措辞谨慎——“增加安全性”而不是“确认”。这里的确认不是二元的;它是累积的。很好的是,奖励被框定为对这种累积的报酬。
“没有人能强迫你接受超出预期发行速率创造出来的任何比特币”
“nobody can force you to accept any bitcoins that were created beyond the expected issuance rate”
查看原文 →作为宽心话溜进来,却是真正的论证:2100 万的上限与其说是由代码强制的,不如说是由每个节点拒绝的意愿强制的。稀缺是一个社会事实。
“实体货币很容易解决双花问题,因为同一张纸币不可能同时出现在两个地方”
“Physical money addresses the double-spend issue easily because the same paper note cannot be in two places at once”
查看原文 →整个问题,一行说完。物理学一直在悄悄地做着记账;把钱数字化,你就得从零开始重建那个约束。
“它们的总计算能力现在超过了世界顶级超级计算机计算操作的总和”
“their combined computational power now exceeds the combined number of computing operations of the world’s top supercomputers”
查看原文 →说得很自豪,但这也是诚实的价签:所有那些计算除了产出它自己的难度之外,不产生任何结果。
“你的密钥,你的币。不是你的密钥,就不是你的币。”
“Your keys, your coins. Not your keys, not your coins.”
查看原文 →一句口号被丢进一本技术手册,作者还在上面签了自己的名字。它起的是道德测试的作用,而不是描述——这恰恰就是为什么大多数用户通不过它,而照样使用交易所。
“大约相当于每天的比特币交易,看一个小时的流媒体视频”
“about the same as watching an hour-long streaming video for each day of Bitcoin transactions”
查看原文 →一个精明的类比——它把主权重新框定成比 Netflix 还便宜。留意它衡量的是什么:带宽,而不是几百 GB 的初始验证。
“还有许多恶意软件应用模仿钱包的设计,坚持要你输入你的恢复码”
“there are also many malware applications that mimic the design of a wallet, insist you enter your recovery code”
查看原文 →这种攻击纯粹是社会性的,它之所以管用,恰恰因为合法的钱包也会问。安全模型最薄弱的一点,是它所训练出来的习惯。
“一旦比特币地址与某个身份关联,其他相关联的比特币交易也可能变得容易识别和追踪——包括更早进行的交易”
“once a Bitcoin address is attached to an identity, other associated Bitcoin transactions may also become easy to identify and track—including transactions made earlier”
查看原文 →“包括更早的”才是刺痛。这里的隐私是追溯性的、不可逆的——一次披露就穿过一份永久的公共记录向后延伸。
“这样他就不必输入爱丽丝的比特币地址,那地址相当长”
“so that he doesn’t have to type in Alice’s Bitcoin address, which is quite long”
查看原文 →二维码被当作便利兜售,但真正的原因是,输错的地址会让钱永远消失。书把这个可怕的部分留在了台下。
“0.001 BTC 是 1 毫比特币(mBTC),或 100000 聪(sats)”
“0.001 BTC is 1 millibitcoin (mBTC) or 100,000 satoshis (sats)”
查看原文 →同一个数量的三个名字,而书没有选一个。这场悬而未决的单位之争,本身就是关于比特币文化的事实。
“几周或几个月之后,这将帮助乔记起他为什么发了这 0.001 个比特币”
“Weeks or months from now, this will help Joe remember why he sent these 0.001 bitcoins”
查看原文 →一句悄悄致命的话:账簿是公开而永久的,然而关于意义的唯一记录,却是乔为自己敲下的一个私人标签。
“交易手续费越高,交易被确认得越快”
“The higher the transaction fee, the faster the transaction will be confirmed”
查看原文 →协议内部出现市场的第一次——你不是在为服务付费,你是在和陌生人竞价争夺空间。
“他即将转出资金,而错误很快就会变得不可逆”
“he is about to transmit money and mistakes will soon become irreversible”
查看原文 →“很快”在承担很多活。不可逆并不是瞬间的——有一个窗口——但书宁可让乔根本感觉不到窗口。
“网络中大多数连接良好的节点收到这笔交易,并第一次看到爱丽丝的地址”
“most of the well-connected nodes in the network receive the transaction and see Alice’s address for the first time”
查看原文 →爱丽丝的“新”地址在几秒钟内就成了全球知识。刚创建的隐私,瞬间被公布。
“爱丽丝的钱包在不断地“监听”新交易”
“Alice’s wallet is constantly "listening" for new transactions”
查看原文 →这个引号是诚实的。一个监听一切的钱包,要么是向整个网络索取一切,要么是请人帮它过滤——而这个选择泄露了爱丽丝是谁。
“用传统金融的术语说,这叫做清算”
“In traditional financial terms this is known as clearing”
查看原文 →这个类比讨好了比特币,也误导了人:清算背后有一个负责的机构,而确认只有概率。
“爱丽丝现在是 0.001 BTC 的自豪所有者,她可以花掉它”
“Alice is now the proud owner of 0.001 BTC that she can spend”
查看原文 →就在上一句,她还只有一个未确认的条目;现在她成了自豪的所有者。十分钟的间隔被叙述过去,而不是被解决。
读后感AI 陪读
这一章先让你相信比特币说得通,再解释为什么
第1章分两条弧线推进。第一条是定义性的、意识形态的:比特币作为一种由密钥控制的虚拟货币,运行在一个点对点网络上,在那里,挖矿既取代了中央银行的发行台,也取代了清算所的账簿,由难度重新调整和一个略低于 2100 万枚的总量上限所约束。第二条是一场戏剧化的演示:乔用二维码交给爱丽丝 0.001 BTC,交易处于未确认状态,一个区块到来,爱丽丝成了所有者。教学法是稳妥的——先概念,再给一个你可以跟着走遍系统的实体——但两条弧线之间的接缝,正是本章修辞所在之处,因为故事悄悄花掉了那些概念尚未挣得的信心。
我一再看穿的,是本章把最难的真相放进令人安心的语法里的习惯。其中最好的一句话几乎是旁白:币是被隐含在交易之中的。没有币——只有一份转移的账簿,所有权是语法,而不是对象。从这一个洞见出发,其余一切随之而来,包括代价。如果所有权只是一个有效的签名,那么占有一把密钥就是所有权,而盗窃在形式上就与花费无法区分;书将花几百页来偿付这笔账。如果 2100 万的上限守得住,那是因为每个节点都拒绝超出发行计划的币——稀缺是一个社会事实,靠集体的意愿来执行,而不单靠算术。而如果双花是核心问题,那是因为物理学一直在悄悄地做着记账:一张纸币不能同时在两个地方,而把钱数字化就意味着要从无到有地重建这个约束。诚实的价签以夸耀的面目出现——超过世界顶级超级计算机的算力,一种唯一的产出就是产出它本身的难度的计算。
继续阅读
我最尖锐的判断,关于最后几段。“清算”是错误的类比,而且错在一个讨好的方向上:清算背后有一个对结果负责的机构,而确认只有不断累积的概率。本章别处其实知道这一点——它说矿工“增加安全性”而不是“确认”,精确而且好——但随后它却是把十分钟的间隔叙述过去,而不是去解决它,爱丽丝在一句话里就从未确认的条目变成了“自豪的所有者”。同样,“错误很快就会变得不可逆”没有给乔留出任何窗口,而窗口恰恰是存在的;二维码被当作便利兜售,而它的真正作用是防止一个会让钱永远消失的输入错误;流媒体视频的类比衡量的是持续的带宽,而不是几百 GB 的初始验证;而“快速、安全、无国界”重重地靠在“可以说”之上,因为十分钟的区块和手续费市场是同一本书后面的章节。手续费那一行,是协议内部出现市场的第一次——你不是在购买服务,你是在和陌生人竞价争夺空间。
隐私的内容是本章最安静地残酷、也最值得重读之处。爱丽丝的新地址,在广播后的几秒钟内就成了全球知识;她的钱包必须“监听”一切,这意味着要么向网络索取一切,要么请人帮忙过滤,而这个选择本身就泄露了她是谁。然后是刺痛:一旦地址与某个身份关联,更早的交易也变得可以追踪。这里的隐私是追溯性的、不可逆的——一次披露就穿过一份永久的公共记录向后延伸。与此同时,这份记录保存了除意义之外的一切:乔为什么发这笔钱,唯一的痕迹是他为自己敲下的一个私人标签。
所以我要对读者说的是:把这一章读两遍,第二遍读得平淡一些,去掉那些鼓励。它提供的每一份便利,都是一份被转移的负担。“你的密钥,你的币。不是你的密钥,就不是你的币。”被作者当作一场道德测试而不是描述签下了名字——这恰恰就是为什么大多数人通不过它而去用交易所,也是为什么索要你恢复短语的钓鱼恶意软件管用:合法的钱包也会问,所以这种攻击利用的是系统训练出来的习惯。就连单位也不肯定下来——BTC、mBTC、聪,同一个数量的三个名字,没有赢家——一场小小的、悬而未决的战争,本身就是关于这种文化的事实。把这一章当作对比特币取代了什么的、现有最清楚的陈述:不是银行,而是我们从未需要说出名字的、物理上和制度上的保证。它用概率、永久性和个人责任来取代它们——这三样东西比那句关于互联网货币的话所透露的要难用得多。
在 FeedLitra 里读第 1 章,每段旁边都有这些卡片。
开始读书第 2 章:比特币如何运作
如果找零输出在协议层面与付款完全相同,一个全新的找零地址,究竟能在链分析面前买到多少隐私?
第 2 章是怎样展开的AI 辅助
开篇:框架与工具。 本章以其统领性的主张开篇——与银行和支付系统不同,比特币不需要信任第三方,因为每个用户都可以用自己的软件验证系统的每个方面。随后它宣布自己的方法:不抽象地解释技术,而是追踪一笔交易穿过整个系统,看它落到区块链上,把机制推迟到后面的章节。在叙事开始之前,它先交给读者一些实用工具——接受地址、txid、区块号或区块哈希的区块浏览器(Blockstream、Mempool.Space、BlockCypher)——外加一条隐私警告:查询你自己的交易,可能会让浏览器的运营者推断出你收到、花费和拥有什么。这条小小的提醒很有代表性:本章靠实践来教学,却也指出实践的代价。
展开:故事与交易的解剖。 叙事正文从爱丽丝开始,她沿用自第1章,在鲍勃的网店里买一集付费播客。鲍勃的结账页生成一个二维码,本章停下来拆解它:它不是一个单纯的地址,而是一个携带地址、金额(0.01577764)、标签和消息的 URI——并附带一条提示:扫描它,但不要汇款。爱丽丝扫描、授权,鲍勃几秒钟内看到了支付。从这个具体时刻起,文字拓宽为解剖。一笔交易被比作复式账簿的一行:输入花费,输出接收,二者之间的缺口就是隐含的手续费。交易串成链——爱丽丝的 Tx2 通过引用(“Tx1:0”)花费乔的 Tx1 的输出,因为真实的交易从不陈述输入的价值,软件必须去查。聪作为协议的原生单位出现。本章随后叠加找零(用 20 美元钞票买 5 美元东西的类比、找零地址应当全新且与付款无法区分的隐私要点,以及鲍勃在 Tx3 中做出的无找零交易)、作为在囤大钞与零钱之间的现金处理平衡的选币,以及三种常见的交易形态:简单支付、合并和批量支付。
转折:从爱丽丝的钱包到网络与挖矿。 叙述随后从交易是什么,转向它如何旅行。钱包无形地完成所有的选取、构建输出和设置手续费,而且——值得注意——可以完全离线地完成,就像在家里写一张支票。一经广播,交易就进入一个由全验证节点组成的、闲谈式的点对点网络;任何节点都行,任何连接都行,几秒钟内它就到达鲍勃,他的钱包认出了一个其密钥可以赎回的输出。这引出了本章真正的支点:传播不等于确认。挖矿作为防伪保护登场,使区块——区块头极其昂贵地形成,却极易检查。本章解释了抽奖的比喻(候选区块被反复哈希,直到输出匹配一个协议模板,写作时大约要尝试 1680 万亿亿次,用一次哈希就能验证),把结果命名为工作量证明,并摆出激励论证:诚实地创建区块,得到补贴加手续费,而改写一笔已确认的交易,则迫使攻击者为一点小收益产出两个区块。
收尾:信心不断累积,然后继续花出去。 最后的乐章把所有这些计算转化为一种分级的安全感。爱丽丝的交易在广播后约五分钟被挖出——一次确认;大约十九分钟后,又一个区块落在它上面,使撤销它需要三个区块;链一路回溯数十万个区块直到创世区块,而按惯例六次确认被视为非常难以逆转。随着堆叠增长,鲍勃的信心上升。本章然后完成了它在开头画出的圆:被嵌入的交易对所有人可见,全节点可以从币的创造起验证它的整个谱系,而轻量客户端只做部分验证,鲍勃则继续花出去——付钱给他的网页设计师戈佩什,把链从乔延伸到爱丽丝,再到鲍勃,再到戈佩什。它以明确的回顾和对前方的许诺结束:我们看着价值从一个所有者转到另一个所有者,其余各章将详细展开钱包、地址、签名、交易、网络和挖矿。
关键论点,以及支撑它们的原文
比特币无需信任任何第三方就能运作,因为每个参与者自己的软件都能自己检查系统的运作。
作者是靠设计而不是断言来演示这一点的:他带着一笔支付走过构造、广播、验证和挖矿,表明每个阶段都是普通软件可以确认的。他指出,更深的技术机制要到后面的章节才讲,所以这只是一个高层次的演示,他还指出,完全独立的检查意味着运行全节点。
“与传统的银行和支付系统不同,比特币系统不需要信任第三方。”
“The Bitcoin system, unlike traditional banking and payment systems, does not require trust in third parties.”
How Bitcoin Works查看原文 →
拥有比特币不是一个账户余额,而是一条可验证的转移链:要花费,你要签署一笔指向某个特定先前输出的交易。
爱丽丝的支付把她从乔那里得到的输出引用为“Tx1:0”——一个 32 字节的交易标识符加上该输出的位置——并把它分成 75000 聪付给播客,20000 聪找零。因为输入的价值没有写在交易里,软件必须去查那个被引用的先前输出,才知道正在移动的是什么,而这恰恰是让历史可审计的原因。
“用比特币的术语说,花费就是签署一笔交易,把价值从先前的一笔交易转给由比特币地址标识的新所有者。”
“In Bitcoin terms, spending is signing a transaction that transfers value from a previous transaction over to a new owner identified by a Bitcoin address.”
How Bitcoin Works › Transaction Inputs and Outputs查看原文 →
挖矿取代了中央权威:只有区块包含有效交易的矿工才能领取奖励,所以成本和奖励被平衡成了安全。
作者指出这项工作的不对称——为了获胜,大约要尝试 1680 万亿亿个候选区块,而验证只需运行一次哈希——以及电力是在任何报酬发放之前就花掉了的这一事实。由于违反规则就会丧失补贴和手续费,矿工通常被推向只包含有效交易。这个数字是个快照,随网络难度而变。
“这种微妙的平衡,在没有中央权威的情况下为比特币提供了安全。”
“This delicate balance provides security for Bitcoin without a central authority.”
How Bitcoin Works › Bitcoin Mining查看原文 →
另外 3 个论点
基于这种激励,作者论证说,诚实的挖矿就是比帮人撤销一笔已确认的支付更划算。
他比较了矿工面临的两个选项:与爱丽丝串通,替换她给鲍勃的付款,意味着要产出两个区块的工作量(替代区块再加上其上的一个,好让网络接受),而诚实行事则意味着产出一个区块,并保留补贴加上它的所有手续费。付出双倍代价只为收取一点旁门的付款,是更糟的交易——这种关于激励的推理,假定没有矿工控制着占优势的哈希率份额。
“这种微妙的平衡,在没有中央权威的情况下为比特币提供了安全。”
“This delicate balance provides security for Bitcoin without a central authority.”
How Bitcoin Works › Bitcoin Mining查看原文 →
改动一笔交易的难度,随它之后挖出的每个区块而上升。
本章跟着时钟走:爱丽丝发出付款约五分钟后,一位矿工找到了包含它的区块,大约 19 分钟后,又一个区块落在它上面,给出两次确认,并把逆转的要求推到三个区块。随着高度增长,链上累计的计算量也增长,这就是为什么六次确认被视为非常难以撤销。
“因为这个新区块是建立在包含爱丽丝交易的区块之上的(这让爱丽丝的交易有了两次确认),爱丽丝的交易现在只有在挖出两个替代区块——外加建在它们之上的一个新区块——才能被改变,总共需要挖出三个区块,爱丽丝才能收回她发给鲍勃的钱。”
“Because this new block is built on top of the block that contained Alice’s transaction (giving Alice’s transaction two confirmations), Alice’s transaction can now only be changed if two alternative blocks are mined—plus a new block built on top of them—for a total of three blocks that would need to be mined for Alice to take back the money she sent Bob.”
How Bitcoin Works › Bitcoin Mining查看原文 →
验证有两种强度,你得到哪一种,取决于你运行的软件。
全节点重放一枚币的整个历史,从它被创造的区块起,经过每一次后续的转移,直到鲍勃的地址,并能自己判定这笔付款有效且可花费。轻量客户端做不到这一点;它满足于检查这笔交易位于区块链中、其后又挖出了几个区块,并据这些工作量推断这笔付款是可靠的。全节点保留每一个已确认的未花费输出,而轻量钱包为了节省资源,只追踪用户自己的。
“轻量客户端可以通过确认交易在区块链中、并且其后已挖出若干区块,来部分验证支付,从而保证矿工曾花费大量努力来承诺它(见“轻量客户端”)。”
“Lightweight clients can partially verify payments by confirming that the transaction is in the blockchain and has several blocks mined after it, thus providing assurance that the miners expended significant effort committing to it (see “Lightweight Clients”).”
How Bitcoin Works › Spending the Transaction查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
为什么付款需要找零
交易输入就像一张纸币:它不能被部分花费,所以如果可用的资金超过价格,钱包必须把它拆成一个给卖家的输出和一个回到花费者的输出。这就是为什么付给鲍勃的同一笔交易,也把爱丽丝剩下的钱付给她,她以后可以再花。
机制 2
昂贵的抽奖,便宜的检查
矿工对候选区块反复哈希,直到输出匹配协议的模板,这目前需要天文数字次的尝试,然而任何人只用一次哈希就能验证获胜者。因为奖励只有在区块遵循共识规则时才能领取,诚实地花费电力是最便宜的收入途径,于是安全在没有任何权威的情况下涌现出来。
机制 3
深度让逆转变得昂贵
节点遵循承载总工作量证明最多的有效链,所以要替换一笔被埋住的交易,就意味着重新挖它的区块、它之上的每个区块,再加一个,才能超过诚实的链。因此,在上面每多一个新区块,攻击者必须重做的工作量就成倍增加,这就是为什么信心随深度增长。
常见误读
六次确认是一种数学上的保证,保证一笔支付永远不会被逆转。
六是关于成本的惯例,不是证明。它标志着这样一个点:重做那些区块再加一个新区块,被判定为贵得离谱,所以这种保证是经济性的、概率性的——一种随深度不断增长的信心,而不是逆转变得不可能的硬性门槛。
“挖在包含爱丽丝交易的区块之上的每个区块,都算作一次额外的确认。”
“Each block mined on top of the one containing Alice’s transaction counts as an additional confirmation.”
How Bitcoin Works › Bitcoin Mining查看原文 →
既然比特币不需要可信的第三方,我安装的任何钱包应用都在替我验证整个系统。
独立的端到端检查属于全节点,它们持有每一个已确认的未花费输出,并重放一枚币从被创造起的历史。许多用户钱包是轻量客户端,只保留所有者自己的输出,并通过包含和深度来部分验证支付——而通过区块浏览器来查询,会让运营者看到你在问什么。
“与传统的银行和支付系统不同,比特币系统不需要信任第三方。”
“The Bitcoin system, unlike traditional banking and payment systems, does not require trust in third parties.”
How Bitcoin Works查看原文 →
第 2 章的核心概念
- 交易输入与输出
- 交易是一条账簿记录:输入花费先前的资金,输出接收它们,剩下的缺口就是矿工的手续费。
- 适用处: 输入和输出有意不平衡;没有写明的差额就是手续费,所以要读出一笔交易的手续费,需要去查它所引用的先前输出。
- 未花费交易输出(UTXO)
- 过去某笔交易遗留下来的、离散而可花费的一块比特币,由钱包追踪,作为新支付的原材料。
- 适用处: 只有全节点持有每一个已确认的 UTXO;轻量钱包只追踪用户自己的,以完整性换取较低的资源占用。
- 找零输出
- 一个付回给花费者的输出,之所以需要,是因为输入不能被部分花费,就像用 20 美元钞票付款后要找零一样。
- 适用处: 协议层面的找零输出与付款无法区分,而当输入几乎等于花费额加手续费时,交易可以完全省略找零。
- 工作量证明
- 一个区块,其区块头需要天文数字次的哈希尝试才能找到,却只需运行一次哈希函数就能检查。
- 适用处: 它只以概率的方式证明付出的努力,其安全建立在奖励只有在遵循共识规则时才能领取之上。
- 闲谈式传播
- 每个节点把它没见过的每一笔新的有效交易转发给它所有的对等节点,所以支付在几秒钟内就泛滥全网。
- 适用处: 因为交易带着所需的全部数据,投递的路径无关紧要——发送者和接收者不需要直接连接。
- 确认
- 挖在包含你交易的区块之上的每个区块,都增加一次逆转的难度计数。
- 适用处: 是一种惯例,而不是证明:六次是关于计算成本的经验法则,而不是绝对的保证。
另外 2 个概念
- 创世区块
- 0 号区块,是此后每一个区块最终都链回的第一环。
- 适用处: 只是链的起点;它对任何单笔交易的有效性不说明任何问题。
- 全节点验证
- 一个节点独立地重放一枚币的整个历史,从它在某个区块中被创造起,直到当前的所有者。
- 适用处: 轻量客户端做不到这一点;它们只确认被包含和深度。
第 2 章划线与批注AI 陪读
“运营者可能猜得出你收到、花费并目前拥有多少比特币”
“the operator may be able to guess how many bitcoins you’ve received, spent, and currently own”
查看原文 →一个埋在入门章节里的隐私警告——它悄悄承认,化名的叙述在好奇心的那一点上漏了。查看你自己的钱,就是破绽。
“每个用户都可以使用运行在自己电脑上的软件来验证运作是否正确”
“each user can use software running on their own computer to verify the correct operation”
查看原文 →整个意识形态,一句话说完:信任被本地验证取代。注意它说的是可以,而不是确实——而本章后面承认,大多数用户运行的是轻量客户端。
“几秒钟之内(和信用卡授权大致相同的时间),鲍勃就看到了这笔交易”
“Within a few seconds (about the same amount of time as a credit card authorization), Bob sees the transaction”
查看原文 →障眼法。鲍勃是在几秒钟内看到它;但它要五分钟或一个小时后才结算。可见性正被悄悄当作确认来兜售。
另外 9 条批注
“输入和输出加起来不一定是同一个数额。”
“The inputs and outputs do not necessarily add up to the same amount.”
查看原文 →优雅的设计选择:手续费从不被写下来,只是由一个差额隐含。用减法来付的钱。
“实际的比特币交易并不明确包含其输入的价值”
“actual Bitcoin transactions don’t explicitly include the value of their input”
查看原文 →一句话说明全节点为何重要——一个输入值多少钱不在交易里,而在历史里。你没有过去,就读不了一笔交易。
“我们给找零输出加了阴影”
“we’ve added shading to the change outputs”
查看原文 →诚实的脚注:图表的清晰,恰恰是协议努力要毁掉的东西。教学法需要撤销隐私。
“人们下意识地在这两个极端之间找到平衡”
“People subconsciously find a balance between these two extremes”
查看原文 →可爱的类比,但回避了真正的利害——选币是一个隐私决定,而不是整洁问题。你把哪些币合并在一起,就透露了你拥有两者。
“就像在家里写一张支票,之后再用信封寄给银行”
“Like writing a check at home and later sending it to the bank in an envelope”
查看原文 →离线签名这一点,是硬件钱包和冷存储的基础,却被当作比喻随口带过。签名与广播是可分开的——那是一种安全架构,而不是一种便利。
“大约 1680 万亿亿(168 billion trillion)”
“about 168 billion trillion”
查看原文 →一个被设计成难以想象的数字,这正是重点——但它也是本章对它一直描述为单纯“平衡”的能源成本,唯一的一点暗示。
“他可以开始相信来自爱丽丝的付款是可靠的”
“he can begin to believe that the payment from Alice can be relied upon”
查看原文 →这里最坦率的一句话。不是证明,不是最终性——是相信,按成本分级。比特币的安全是一个穿着密码学外衣的经济学论证。
“也许是爱丽丝把她之前付给鲍勃的钱,分一部分付给矿工”
“perhaps with Alice paying miners a share of the money she previously paid Bob”
查看原文 →一章入门内容把贿赂明说出来,很少见。诚实只是更便宜的选项,而不是这个系统的美德。
“按惯例,任何有六个以上确认的区块,都被认为非常难以改变”
“By convention, any block with more than six confirmations is considered very hard to change”
查看原文 →“按惯例”承担了很重的活。六是民间传说被硬化成了策略——协议里没有任何东西说要六个。
读后感AI 陪读
看似无需信任的东西,实际上是对矿工激励的信任
本章的方法是让一次小小的购买承载整个架构,而它多半成功了:通过跟着 0.0157 BTC 从爱丽丝的手机,到鲍勃的收银机,再到戈佩什的发票,它挣得了这些概念——UTXO、找零、作为差额的手续费、确认深度——而不是定义它们。最让我印象深刻的,是开篇的承诺与结尾的承认之间的距离。它开篇讲的是无需信任:没有第三方,一切自己验证。它结尾时,鲍勃能够“开始相信”这笔付款靠得住,因为不诚实会让矿工多付两个区块而不是一个区块的代价。那不是无需信任;那是信任被转移到一个激励结构里,以电力来定价。本章对此是诚实的——它直截了当地点出了贿赂的情景——但这个框架仍然让读者觉得自己被交到了确定性。另外两处接缝:隐私的叙述不稳定(区块浏览器的警告、被加了阴影的找零输出、把关联当作只是整洁问题的选币类比,都指向一个本章不肯完全打开的监视表面),而“几秒钟,就像信用卡”这句话,把传播与结算混为一谈,恰好是商家被烫到的方式。本章最好的一句话是最安静的那句:交易并不包含它们自己的输入值。你无法孤立地读懂一笔比特币交易——意义存在于它背后的链里。这才是全节点存在的真正原因,也是整个东西被称为区块链的真正原因。
在 FeedLitra 里读第 2 章,每段旁边都有这些卡片。
开始读书第 3 章:比特币核心:参考实现
节点在验证每一条规则时,究竟检查了什么?
第 3 章是怎样展开的AI 辅助
本章根本不是从软件开始的;它从一个激励开始。作者的开场动作是观察到,人们之所以交出商品和服务,只是因为他们期望花掉所收到的东西,这意味着伪造的或悄悄贬值的钱,对接收方来说是个问题,而不是抽象的东西。从这一个经济学事实,本章推出了它的主题:如果你对自己接受的钱是否健全有个人的利害关系,那么就值得运行一个程序,在你控制的硬件上,对照每一条规则检查每一笔已确认的交易。只有在确立了这个动机之后,本章才给那个东西命名——全验证节点——于是这个工具是作为读者已经感觉到的那个问题的答案而到来的。
展开:谱系,然后是构建
第二个乐章是历史性的,并确立权威。作者追溯代码的传承:最初那个程序就叫“Bitcoin”,多年来被大幅改写成今天的比特币核心,现在由一个开放的志愿者社区承担,到 2023 年贡献者超过 1000 人,其中大约有十来人接近全职,另有几十人兼职。这段谱系的要点,是为“参考实现”这个说法辩护——持续而广泛的维护,才使一份代码库成为别人可以拿来衡量自己的标准。值得指出本章在这里小心的限定,它很容易被误读:作为参考实现,与作为规范并不是一回事。规则本身存在于白皮书和自 2011 年以来记录了大多数重大变更的、带编号的改进提案里;比特币核心展示的是主要部分打算如何构建,而不是什么是按定义被允许的。
从谱系出发,本章转向实用,走一遍单一的、不间断的序列:克隆仓库,选择一个发布标签,配置,编译,安装,运行,然后配置节点本身。这最后一步是本章不再是配方、开始教授取舍的地方。作者把账单直截了当地量化——一开始要下载并处理超过 500 GB,仅离线十天就要约 4 GB 的追赶流量,多年运行至少需要 1 TB 磁盘,且都预计会增长——然后指出,尽管如此仍有成千上万个节点在运行,有些在一块 35 美元的树莓派上,从而把这个数字翻转过来。教训是在廉价硬件上的可负担性,而不是限制的消失。因此有两种成对的配置:修剪让节点验证一个区块之后就删掉它,限制磁盘使用,但完整的数据集仍然必须被下载和检查,所以修剪买到的是存储,而不是带宽。而且因为交易索引只能在你仍持有的区块里解析一笔交易,修剪和按 txid 查找朝相反的方向拉扯——这恰恰就是为什么接下来展示的是完全索引的配置,与受约束的配置并列,而不是取代它。
转折:从构建到盘问
本章的铰链是节点不再是你安装的东西、而成了你质询的东西的那一刻。载体是 JSON-RPC API,而作者主张从命令行开始,理由是教学上的:bitcoin-cli 让你交互地尝试程序以后可以做的一切。演示是自带文档的——bitcoin-cli help 列出每个可用的调用,help getblockhash 打印参数、结果类型,以及两个现成可复制的示例,一个给 bitcoin-cli,一个给 curl。运行 getblockhash 1000 然后返回一个固定的哈希,在任何读者的机器上都应当匹配,这同时证明了三件事:节点在运行,它接受命令,它持有区块数据。从状态命令出发,本章转向交易和区块的探索,解码爱丽丝的交易作为演示案例:一个输入指向先前已确认的输出,两个输出——给鲍勃的付款和回到爱丽丝的找零。因为每个输入都指名一个先前的输出,取那个被引用的 txid 再依次解码,就让所有权历史可以一步步向后追溯。(本章附带的一个提醒:找不到 txid,并不证明支付失败。在确认之前,交易可以被以改变其 ID 的方式改动,所以找不到只说明你的副本与网络的不同;一旦它进了区块,ID 就固定了,除非发生重组。)
收尾:回报被重申为地基
最后一段在收窄主题之前,先拓宽了接口。作者展示了同样的调用通过带 cookie 认证的 curl——解释说比特币核心在每次启动时都会把一个新的随机 RPC 密码写进 .cookie 文件,这就是为什么命令不用设置凭据就能工作,也是为什么复制过一次的密码在重启之后会悄悄失效,而 rpcauth 是持久访问的办法——然后转向 python-bitcoinlib 脚本,最后是替代的客户端。从源代码走到一个可编程的接口之后,本章落在它的收尾主张上:来自你自己节点的数据之所以可信,是因为你验证了它,而不是因为某个权威为它担保。节点运营者持有每一枚可花费比特币的、本地验证过的副本,不留下任何需要依赖的第三方。最后一笔是前瞻性的——你控制的计算机上你控制的软件——并把第3章重新定位为基础工作:后面的章节是为了解释这个节点和钱包所应用的规则,而在这里养成的、检查已验证数据的习惯,正是全书其余部分所依托的东西。
关键论点,以及支撑它们的原文
比特币核心被视为参考实现,因为它源自中本聪最初能运行的代码,并由一个开放的志愿者社区一路传承下来。
作者追溯了这条谱系:最初那个就叫“Bitcoin”的程序,多年来被大幅改写成今天的比特币核心,到 2023 年源码贡献者已超过 1000 人,其中大约有十来人接近全职,另有几十人兼职。这种持续而广泛的维护,才使这份代码库成为其他实现可以拿来匹配自己的标准。
“那个最初的实现,当时简称“Bitcoin”,已经被大幅修改和改进。”
“That first implementation, then simply known as "Bitcoin," has been heavily modified and improved.”
Bitcoin Core: The Reference Implementation › From Bitcoin to Bitcoin Core查看原文 →
来自你自己节点的数据之所以可信,是因为你验证了它,而不是因为某个权威为它担保。
作者的推理是,节点运营者持有每一枚可花费比特币的、本地验证过的副本,所以在检查一笔交易是否有效时,没有第三方可以依赖。你在本章后面检查的区块和交易,恰恰因为这个理由才有分量——你的机器自己应用了规则。
“然后我们将检查来自你节点的区块、交易和其他数据,这些数据是权威的——不是因为某个强大的实体指定它们为权威,而是因为你的节点独立地验证了它们。”
“We’ll then inspect blocks, transactions, and other data from your node, data which is authoritative—not because some powerful entity designated it as such but because your node independently verified it.”
Bitcoin Core: The Reference Implementation查看原文 →
顺着这个回报,运行节点是一项真正的资源投入,所以要不要做,取决于你的存储、带宽、隐私和开发需求。
作者把账单量化了:一开始要下载并处理超过 500 GB,仅离线十天就要约 4 GB 的追赶流量,多年运行至少需要 1 TB 磁盘——这些数字预计会增长。他又把它翻过来,指出尽管如此仍有成千上万个节点在运行,有些在一块 35 美元的树莓派上,这表明成本在廉价硬件上是可负担的,而不是限制消失了。
“然而,运行节点一开始需要下载并处理超过 500 GB 的数据,此后每天约 400 MB 的比特币交易。”
“Running a node, however, requires downloading and processing over 500 GB of data initially and about 400 MB of Bitcoin transactions per day.”
Bitcoin Core: The Reference Implementation › Running a Bitcoin Core Node查看原文 →
另外 3 个论点
命令行是学习节点接口的正确地方,因为 bitcoin-cli 让你交互地尝试程序所能做的一切。
作者用内置的文档来演示:bitcoin-cli help 列出每个可用的调用,help getblockhash 打印参数、结果类型,以及两个现成可复制的示例——一个给 bitcoin-cli,一个给 curl。运行 getblockhash 1000 然后返回一个固定的哈希,在任何读者的机器上都应当匹配,同时证明节点在运行、在接受命令、并持有区块数据。
“命令行让我们可以交互地试验那些同样可以通过 API 以编程方式使用的能力。”
“The command line allows us to experiment interactively with the capabilities that are also available programmatically via the API.”
Bitcoin Core: The Reference Implementation › Bitcoin Core API查看原文 →
因为每个交易输入都指名一个先前交易的输出,这个接口让读者可以从一个 txid 跳到另一个 txid,沿着所有权历史向后追溯。
作者解码了爱丽丝的交易作为演示案例:它有一个指向先前已确认输出的输入,和两个输出——给鲍勃的付款和回到爱丽丝的找零。取那个被引用的 txid,再依次解码那笔交易,就让这条链可以一步步地追溯。
“从一笔交易跳到另一笔交易,我们可以顺着币从一个所有者传给下一个所有者的过程,追溯一条交易链。”
“Jumping from transaction to transaction, we can follow a chain of transactions back as the coins are transmitted from one owner to the next.”
Bitcoin Core: The Reference Implementation › Exploring and Decoding Transactions查看原文 →
本章的收尾要点:运行你自己的全节点,把对外部权威的信任,转化为对每条规则的本地检查。
作者把回报框定为:你控制的软件,运行在你控制的计算机上,并告诉读者,后面的章节是为了解释这个节点和钱包所应用的、保护他们的钱和隐私的规则——在这里养成的验证数据的习惯,是后面一切的基础。
“从现在起,你可以独立地使用你控制的软件——在你控制的计算机上——来验证你收到的任何比特币都遵循比特币系统中的每一条规则,而无需信任任何外部权威。”
“From now on you can independently use software you control—on a computer you control—to verify that any bitcoins you receive follow every rule in the Bitcoin system without having to trust any outside authority.”
Bitcoin Core: The Reference Implementation › C#查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
为什么人们想自己检查钱
作者从一个简单的经济学事实出发:人们交出商品和服务,只是因为他们期望以后能花掉所收到的钱。伪造的或悄悄贬值的钱,可能最终花不出去,所以每个接收者对检查完整性都有直接的利害关系。这种激励,才使得运行那个在你自己的机器上、对照每一条规则验证每一笔已确认交易的软件,变得值得。
机制 2
修剪省磁盘,却要付出查找的代价
节点可以验证一个区块然后删掉它,限制链在小机器上占用多少磁盘。但完整的数据集仍然必须先被下载和检查,所以修剪买到的是存储,而不是带宽。而且由于交易索引只能在你仍保留的区块里解析一笔交易,修剪和按 txid 查找朝相反的方向拉扯——这就是为什么作者把完全索引的配置与受约束的配置配成一对。
机制 3
cookie 密码是如何工作的
比特币核心每次启动,都会把一个新的随机 RPC 密码写进数据目录里的 .cookie 文件,而 bitcoin-cli 会自己读取那个文件。这就是为什么命令不用设置凭据就能工作,也是为什么复制过一次的密码在重启之后会失效——持久的访问需要改用 rpcauth 辅助工具。
常见误读
既然比特币核心是参考实现,它的代码就是规范——比特币核心做的任何事,按定义就是规则。
比特币核心展示了大多数主要部分打算如何构建,这就是为什么其他实现把它当作要匹配的标准,但规范本身存在于白皮书,以及自 2011 年以来记录了大多数重大变更的、带编号的改进提案里。
“比特币核心是比特币系统的参考实现,意思是它提供了技术的每个部分应当如何实现的参照。”
“Bitcoin Core is the reference implementation of the Bitcoin system, meaning that it provides a reference for how each part of the technology should be implemented.”
Bitcoin Core: The Reference Implementation › From Bitcoin to Bitcoin Core查看原文 →
如果我通过自己的节点查一笔交易的 ID,什么都没有返回,那这笔付款显然没有成功。
在确认之前,交易可以被以改变其 ID 的方式改动,所以找不到某个 ID,只说明你拿到的那个版本不是网络所拥有的——这笔付款很可能已经以另一个 ID 被处理了。一旦交易进了区块,ID 就固定了,除非某次链重组移除了那个区块。
“区块链中没有 txid,并不意味着该交易没有被处理。”
“Absence of a txid in the blockchain does not mean the transaction was not processed.”
Bitcoin Core: The Reference Implementation › Exploring and Decoding Transactions查看原文 →
第 3 章的核心概念
- 全验证节点
- 你自己电脑上的软件,对照每一条系统规则检查每一笔已确认的交易,所以无需信任任何外部方。
- 适用处: 验证是本地的、权威的,但它要花费数百 GB 的存储、每天的带宽,以及漫长的初始同步。
- 参考实现
- 展示这项技术的每个部分应当如何构建的代码库,这样其他实现就有了可以匹配的标准。
- 适用处: 对大多数主要部分,它是参照,但白皮书和 BIP 记录的才是规范本身。
- 比特币改进提案
- 自 2011 年以来规定了比特币大多数重大变更的带编号文档,在全书中以编号引用。
- 适用处: 涵盖 2011 年之后的新增内容;系统最早的部分则由白皮书描述。
- 修剪
- 验证之后删除旧区块,以限制区块链在受限机器上占用多少磁盘。
- 适用处: 只减少存储的数据;整个数据集仍然要下载,而且有些数据无法修剪。
- 交易索引
- 一个可选的、包含所有交易的数据库,让你能按 ID 查找任何交易,而不只是与钱包有关的交易。
- 适用处: 只有当包含该交易的区块没有被修剪时才管用,而且之后再启用它会迫使重建索引。
- JSON-RPC 接口
- 比特币核心把它的功能暴露为经由 HTTP 发送、带 JSON 正文的远程过程调用,所以任何程序或 bitcoin-cli 辅助工具都可以驱动节点。
- 适用处: 它是 8332 端口上需要凭据的本地管理接口;它不是点对点的网络协议。
另外 3 个概念
- 初始区块下载
- 新节点先拉取区块头,以找到工作量证明最多的链,然后下载并验证每一个完整的区块。
- 适用处: 只在追赶期间适用;一旦同步完成,getblockchaininfo 会报告 initialblockdownload 为 false。
- 交易延展性
- 在确认之前,交易可以被修改,使其 txid 发生变化,所以找不到某个 txid,并不能证明这笔付款从未被处理。
- 适用处: 交易进入区块之后,txid 就固定了,除非某次重组移除了那个区块。
- Cookie 认证
- 每次启动时,比特币核心都会把一个随机的 RPC 密码写进数据目录里的 .cookie 文件,bitcoin-cli 会自动读取它。
- 适用处: 密码在每次重启时都会变;持久的凭据需要改用 rpcauth.py 辅助工具。
第 3 章划线与批注AI 陪读
“权威的数据——不是因为某个强大的实体指定它们为权威,而是因为你的节点独立地验证了它们”
“data which is authoritative—not because some powerful entity designated it as such but because your node independently verified it”
查看原文 →全书的意识形态论点,被当作一句关于数据的话溜进来。权威从机构转移到了计算。
“中本聪想在发表关于它的论文之前,先确保实现能用”
“Satoshi wanted to make sure the implementation worked before publishing a paper about it”
查看原文 →颠倒了学术的顺序:先代码,后论文。对一个领域的无声嘲讽,那里白皮书常常先于任何能运行的东西。
“比特币核心是比特币系统的参考实现”
“Bitcoin Core is the reference implementation of the Bitcoin system”
查看原文 →这是没有说出口的尴尬:一个去中心化的系统,其规则最终由一份代码库的行为来定义,连 bug 也算在内。
另外 10 条批注
“如果内容变得太密集(而你其实并不是在搭建开发环境),可以随意跳到下一章”
“If the material becomes too dense (and you’re not actually setting up a development environment) feel free to skip to the next chapter”
查看原文 →一位技术作者少有的诚实。也是一个暗示:编译演练是你读到时最可能已经过时的部分。
“你大概不应该在它上面运行比特币节点”
“you should probably not run a Bitcoin node on it”
查看原文 →主权的推销直直撞上了带宽账单。自我验证是良好基础设施的一种特权。
“你不想向第三方披露哪些交易属于你的钱包。”
“You do not want to disclose to third parties which transactions belong to your wallet.”
查看原文 →清单上最强的理由,却被列在第二位而不是第一位——通过别人的节点泄露隐私,是大多数用户从未察觉的损失。
“blocks": 0, "headers": 83999,”
查看原文 →他们展示了未完成的状态,很好。先是区块头,然后是区块体——节点在费神去相信其中任何内容之前,先决定哪条链的工作量最大。
“交易 ID(txid)不具权威性。区块链中没有某个 txid,并不意味着该交易没有被处理。”
“A transaction ID (txid) is not authoritative. Absence of a txid in the blockchain does not mean the transaction was not processed.”
查看原文 →被当作随口的提示丢了出来,但这是书里后果最严重的陷阱之一——交易所恰恰因为这个误解亏过钱。它值得一节,而不是一个框。
“这个区块之前 11 个区块的中位时间(一种矿工更难操纵的时间度量)”
“the median time of the 11 blocks that precede this block (a time measurement that’s harder for miners to manipulate)”
查看原文 →整个对抗性的设计哲学,压缩在一个括号里:连时钟也被假定为敌对的。比特币里没有任何东西被信任,连时间戳也不例外。
“比特币核心会在每次启动时创建一个随机密码,放在数据目录下,名为 .cookie。”
“Bitcoin Core will create a random password on each start and place it in the data directory under the name .cookie.”
查看原文 →优雅:认证被简化为文件系统的权限。如果你能读那个目录,你就已经是所有者了——没有凭据可泄露或遗忘。
“前面两个例子都相当简单。你其实不需要一个程序来运行它们”
“Both of the preceding examples are rather simple. You don’t really need a program to run them”
查看原文 →技术书中少有的诚实——承认这个演示还不足以为自己辩护,然后才挣得下一个例子。通过承认读者没说出口的“那又怎样?”来教学。
“有些区块浏览器报告的总价值不包括奖励,也不包括手续费。看看你能不能找出区别。”
“Some block explorers report the total value excluding the reward and excluding the fees. See if you can spot the difference.”
查看原文 →真正的教训不是算术——而是两个来源可以都“正确”,却不一致。运行你自己的节点,意味着你来决定这个数字意味着什么。
“无需信任任何外部权威”
“without having to trust any outside authority”
查看原文 →本章整条弧线落在这里:同步区块的那乏味的一天,从来不是为了设置,而是为了买下这句话。
读后感AI 陪读
枯燥就是论证,是被允许相信的代价
第3章是书不再谈论比特币、而让你自己去建造它的一章。它以一个伪装成关于数据的旁白的论点开篇——你节点的数据是权威的,不是因为有谁指定它如此,而是因为你验证过它——然后花了三十页,让你用艰苦的办法挣得这句话:克隆仓库,固定一个发布标签,配置,编译,安装,运行,同步。这个弧线是有意的。结尾的回报句(“无需信任任何外部权威”)与开头那句是同一个主张;中间的一切,是被允许相信它所付出的代价。乏味就是论证。
中间展开的是一个把历史转入实践的动作。中本聪是先写代码,后写论文的——颠倒了学术惯例,也是对一个领域的无声责备,那里白皮书如今常常先于任何能运行的东西——而那最初的实现成了比特币核心,即“参考实现”。本章把这件事说得直白,并拒绝在这种尴尬面前停留:一个卖点就是没有人当家做主的系统,其共识规则在最后的意义上,却由一份代码库观察到的行为来定义,连 bug 也算在内。然后是安装的机制,在这里作者们做了少见的事,告诉你如果变得密集就跳过去——诚实,同时也是一个暗示:这是在你读到时最可能已经过时的部分。然后是配置,在这里主权的推销撞上了现实:存储、带宽、索引的取舍,以及直截了当的建议:在某些网络连接上你就是不应该运行节点。自我验证原来是良好基础设施的一种特权。运行节点的理由清单,悄悄把最强的一条——使用别人的节点会告诉他们哪些交易是你的——埋在第二位,这倒符合大多数用户对一种他们从未察觉的损失的排序。后半部分把编译好的二进制变成一件仪器:bitcoin-cli help、链状态、交易、区块,然后是带 cookie 认证的 curl 和 python-bitcoinlib。在这里作者们继续教得很好——他们承认最初的脚本并不能为自己辩护(“你其实不需要一个程序来运行它们”),然后才挣得一个更难的例子,这就是诚实的教学法的样子。
继续阅读
本章最尖锐的东西,是作为旁白夹带进来的。显示 blocks: 0、headers: 83999 的同步输出,用两行话就是一整个协议——先拿区块头,这样节点在同意相信其任何内容之前,先决定哪条链的工作量最大。括号里说区块时间用前面十一个区块的中位数、“矿工更难操纵”,压缩了整个对抗性的设计哲学:这里没有任何东西被信任,连时钟都不例外。cookie 文件把认证简化为文件系统的权限,这恰恰优雅在没有凭据可泄露。而关于区块浏览器报告不同总额的习题,教的是比算术更好的东西——两个来源可以都对,却仍然不一致,而运行你自己的节点,就是你决定这个数字意味着什么的办法。唯一真正放错位置的,是警告 txid 不具权威性,它不在链上并不意味着交易没有被处理。这被当作一个提示丢了出来。交易所恰恰因为这个误解真的亏过钱;它值得一节,而不是一个框。
我要对读者说的是:别把它当作可有可无的系统管理员章节。命令会过时——如果你想让演练对得上,就固定书里指名的那个标签,并且无论如何要去查阅当前的文档。但习惯不会过时。你获得的不是一个运行的守护进程;而是一种证据的标准。从这里起,当书说“节点检查 X”时,你有地方可以去看。而如果你的网络连接或磁盘确实承受不了,也请把这一章读完,并诚实地对自己承认,此后你看到的每个余额,都附带着别人的一句话——这恰恰就是开篇那句话要消除的依赖。
在 FeedLitra 里读第 3 章,每段旁边都有这些卡片。
开始读书第 4 章:密钥与地址
OP_CHECKSIG 是怎样一步一步地对栈求值的?
第 4 章是怎样展开的AI 辅助
开篇:私密支付的问题。 本章并不是从数学开始的,而是从一个需求开始的。爱丽丝必须付钱给鲍勃,而且必须私密地进行——这意味着鲍勃必须能够收到钱,而不透露任何会让别人把钱拿走的东西。这个要求,正是公钥密码学存在要满足的,而本章按需求所要求的顺序把它搭建起来。首先是私钥,它不过是一个非常大的随机数;作者在这里的要点是,密钥的强度只取决于它背后的随机性,他让这一点变得生动:原则上你可以抛 256 次硬币就得到一把可用的密钥,同时警告说,任何不到真随机的做法都会严重削弱安全——可预测的密钥意味着任何人都能拿走它守护的币(候选数字还必须小于曲线的阶 n)。从私钥出发,椭圆曲线乘法只朝一个方向产生公钥:正向容易计算,反向不可行。接着有两个进一步的动作,把本章的主题压缩成它的现代形态:脚本取代交易里的原始密钥,哈希承诺把密钥缩成地址。
展开:每一层为何被加上。 点出这些层之后,本章解释每一层买到了什么。脚本的到来,是因为花费条件需要比“一把密钥,一个签名”更丰富——脚本字段允许在普通的签名检查之外(或代替它)执行额外的操作,作者的例子是一个要求两个公钥和两个匹配签名的输出。这源于一次真实的失败:较早那种向 IP 地址付款的风格,要求接收者的钱包在线且可达,从未流行起来,近十年里没有任何广泛使用的程序支持它。哈希则解决了一个纯粹是人类尺度的问题。早期开发者所知道的最短密钥有 65 字节——130 个十六进制字符——长得没法大声念出来,也没法可靠地复制;SHA256 后接 RIPEMD-160,把它压缩成一个 20 字节的指纹,尽管作者承认中本聪从未解释为什么选这一对。P2PKH 展示了这个机制的回报:付款人把币锁到那个简短的指纹上,花费者只在之后才提供完整的密钥和签名,于是脚本复制该密钥,对它做哈希,与存下的指纹比较,然后检查签名。接收者只需要事先交出指纹。但仅仅紧凑还不够,本章立刻补上互补的要求:十六进制这类普通编码对输入错误毫无保护,所以 base58check 加上一个版本字节,并在末尾附加一个四字节的双重 SHA 校验和,钱包软件在解码时重新计算它,并在钱动之前用它拒绝格式错误的地址。压缩公钥(存 x 加一个奇偶性前缀)和 P2SH(承诺于一个赎回脚本而不是一把密钥),作为同一个承诺思想的进一步应用,随之而来。
转折:优势变成了弱点。 本章随后反转了它自己的论证。让地址变短的那些 160 位承诺,对新钱包来说现在太弱了,新钱包应当使用提供 128 位抗碰撞性的地址类型。推理对弱点何时起作用是精确的。如果只有一方构建地址,攻破它就意味着找到一个原像——接近 2^160 的工作量,而作者强调这里没有迫在眉睫的威胁。但当攻击者影响被承诺的内容时,他只需要两个相撞的输入,工作量就塌缩到大约 2^80——本章通过指出截至 2023 年初全体矿工合起来每小时执行大约这么多次哈希,让这个数字变得具体,并附带说明:矿工使用的是另一种哈希函数,所以他们的硬件不能直接用来对付 HASH160。这就是 bech32 的动机,而对 bech32 自身缺陷的叙述,是本章对工程上的谨慎最尖锐的说明。Bech32 的错误检测保证,假定地址保持其原来的长度,所以插入或删除单个末尾的“q”可以溜过校验和,把资金重定向到一个要么任何人都花不了、要么所有人都能花的输出。开发者们没有强迫每个钱包去管控地址长度,而是详尽地分析了这个问题,发现改动一个校验和常数就堵上了这个缺口——此后,最多五个字符的未被检测到的改动,发生的概率不到十亿分之一。那一个被改变的常数,就是 bech32 与 bech32m 的全部区别。本章随后摆出由此得到的地址解剖:人类可读的前缀,分隔符“1”,一个版本字符,一个 2 到 40 字节的程序,以及一个 6 字符的校验和。选数字“1”而不是冒号,反映的是同样的留心——有些系统在冒号处就会停止双击选择。
收尾:格式,以及两种过时的做法。 本章结束时回到它起步的私钥,现在通过它的各种编码来看待它。一个数字支撑着所有编码;十六进制和 WIF 是呈现方式,不是不同的密钥。在这里,本章纠正了两个可能的误读。第一个是以为一把私钥对应一个地址,所以导入旧密钥总能找到钱:事实上,一把私钥产生两个有效地址,因为对压缩公钥做哈希产生的承诺,与对未压缩形式做哈希的不同,而只扫描一种格式的钱包,可能让资金无法花费——这就是为什么导入必须知道该找哪一种。与此相关,“压缩私钥”是个用词不当:它是一种带有 01 后缀的 WIF 导出,该后缀告诉软件只从同一个未改变的 256 位数字推导出压缩公钥。第二个纠正以一条警示的笔调结束本章。把密钥打印在纸上并不是最安全的冷存储;作者称纸钱包对大多数用户来说是过时而危险的,因为生成过程涉及微妙的陷阱——首先是生成的代码可能藏着后门,而许多比特币恰恰是这样被偷走的。恢复码和硬件签名设备是被推荐的替代品。靓号地址也屈从于同样的转变:靠暴力破解得到,不适合确定性备份,并且容易把付款关联起来,暴露交易对手,而不只是所有者。于是,本章结束在它开始的地方——爱丽丝需要私密地付钱给鲍勃——它已经表明,隐私和安全现在更少依赖聪明的密钥,而更多依赖围绕它们建立的格式和工具。
关键论点,以及支撑它们的原文
私钥的好坏只取决于它所来自的随机性,所以它必须取自一个密码学上安全的熵源。
作者指出,原则上你可以抛 256 次硬币就得到一把可用的密钥,但警告说,任何不到真随机的过程都会严重削弱安全——可预测的密钥意味着任何人都能拿走它守护的币。候选数字还必须小于曲线的阶 n。
“生成密钥的第一步,也是最重要的一步,是找到一个安全的随机性来源(计算机科学家称之为熵)。”
“The first and most important step in generating keys is to find a secure source of randomness (which computer scientists call entropy).”
Keys and Addresses › Private Keys查看原文 →
比特币从把密钥和签名直接放进交易,转向使用脚本,这样花费条件就可以比“一把密钥,一个签名”更丰富。
脚本字段允许在普通的签名检查之外(或代替它)执行额外的操作;作者的例子是一个要求两个公钥和两个匹配签名的输出。这源于较早那种支付风格的失败,那种向 IP 地址付款的方式要求接收者的钱包在线且可达——它从未流行起来,近十年里没有任何广泛使用的程序支持它。
“这些字段允许在验证签名与公钥相符之外(或代替它)执行额外的操作。”
“These fields allow additional operations to be performed in addition to (or instead of) verifying that a signature corresponds to a public key.”
Keys and Addresses › Output and Input Scripts查看原文 →
把公钥哈希成一个简短的承诺,才使接收的数据小到可以用手交给付款人。
早期开发者所知道的最短密钥有 65 字节,即 130 个十六进制字符——长得没法大声念出来,也没法可靠地复制。通过 SHA256 再 RIPEMD-160,把它压缩成一个 20 字节的指纹,解决了这个实际问题,尽管作者承认中本聪从未解释为什么选这一对哈希。
“出于中本聪从未说明的原因,比特币最初的版本对公钥做承诺的办法,是先用 SHA256 对密钥做哈希,再用 RIPEMD-160 对该输出做哈希;这产生了一个对公钥的 20 字节承诺。”
“For reasons Satoshi Nakamoto never stated, the original version of Bitcoin made commitments to public keys by first hashing the key with SHA256 and then hashing that output with RIPEMD-160; this produced a 20-byte commitment to the public key.”
Keys and Addresses › Legacy Addresses for P2PKH查看原文 →
另外 3 个论点
顺着这一点,仅有紧凑还不够:地址需要内置的校验和,因为一次抄写的失误就可能让币永远无法花费。
十六进制这类普通编码对输入错误毫无保护,所以 base58check 加了一个版本字节和一个四字节的双重 SHA 校验和。钱包软件在解码时重新计算该校验和,并拒绝任何不匹配的地址,这在钱动之前就拦住了输错的地址。
“有一些常用的字节值编码,比如十六进制,但复制承诺时犯的任何错误,都会导致比特币被发送到一个无法花费的输出,永远丢失。”
“There are commonly used encodings for byte values, such as hexadecimal, but any mistake made in copying a commitment would result in the bitcoins being sent to an unspendable output, causing them to be lost forever.”
Keys and Addresses › Legacy Addresses for P2PKH查看原文 →
把论证反过来,恰恰是让地址变短的那些 160 位承诺,对新钱包来说太弱了,新钱包应当使用提供 128 位抗碰撞性的地址类型。
作者强调,对独自创建新地址的人没有迫在眉睫的威胁,但当攻击者影响被承诺的内容时,大约 2^80 次哈希就够了——而截至 2023 年初,全体矿工合起来每小时执行大约这么多次。需要说明的是,矿工使用的是另一种哈希函数,所以他们的硬件不能直接用来对付 HASH160。
“尽管我们不认为对创建新 P2SH 地址的人存在任何迫在眉睫的威胁,但我们建议所有新钱包都使用较新的地址类型,以消除对地址碰撞攻击的担忧。”
“Although we do not believe there is any immediate threat to anyone creating new P2SH addresses, we recommend all new wallets use newer types of addresses to eliminate address collision attacks as a concern.”
Keys and Addresses › Legacy Pay to Script Hash (P2SH)查看原文 →
Bech32m 通过改动一个常数修复了 bech32,此后最多五个字符的未被检测到的改动,发生的概率不到十亿分之一。
开发者们详尽地分析了这个问题,发现这一个常数的改动就足够了;替代方案本来是限制地址长度,因为没有限制的话,增删一个“q”可能把资金送到一个要么无法花费、要么任何人都能花费的输出。相关的细节打磨显示出同样的留心:分隔符是数字“1”而不是冒号,因为有些系统在冒号处就会停止双击选择。
“开发者们详尽地分析了 bech32 的问题,发现改动其算法中的一个常数就能消除这个问题,确保任何最多五个字符的插入或删除,未被检测到的概率都低于十亿分之一。”
“Developers exhaustively analyzed the bech32 problem and found that changing a single constant in their algorithm would eliminate the problem, ensuring that any insertion or deletion of up to five characters will only fail to be detected less often than one time in a billion.”
Keys and Addresses › Bech32m查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
为什么一个密钥哈希就足以收到款
付款人把币锁到密钥的一个 20 字节指纹上;之后花费者提供完整的密钥和签名,脚本复制它、哈希它,并在检查签名之前,与存下的指纹比较。所以接收者只需要事先交出简短的指纹,而不是那 65 字节的密钥。
机制 2
攻击者选择的输入如何缩减 160 位的安全
当只有一方构建地址时,攻破它意味着找到一个原像,那接近 2^160 的工作量。但如果攻击者帮着选择被承诺的内容,他只需要两个相撞的输入,工作量降到约 2^80——而挖矿网络每小时已经执行这么多次哈希了。
机制 3
bech32 里缺失“q”的盲区
Bech32 的错误保证假定地址保持其原来的长度,所以插入或删除单个末尾的“q”可以溜过去,把资金重定向到一个没人或任何人都能花的输出。开发者们没有强迫钱包管控长度,而是改动了校验和里的一个常数,堵上了这个缺口。
常见误读
既然重要的是私钥,那么一把私钥就对应一个地址——所以把旧密钥导入新钱包,总能找到钱。
同一把私钥产生两个不同的有效地址,因为对公钥的压缩形式做哈希所产生的承诺,与对未压缩形式做哈希的不同。只扫描两种格式之一的钱包,可能让资金无法花费,这就是为什么导入必须知道该找哪种格式。与此相关,所谓的“压缩私钥”根本不是一把缩短的密钥——它是一种带有 01 后缀的 WIF 导出,该后缀告诉软件只从同一个未改变的 256 位数字推导出压缩公钥。
“未能扫描正确的类型,可能导致用户无法花费他们的全部余额。”
“Failure to scan for the correct type can lead to the user not being able to spend their full balance.”
Keys and Addresses › Compressed Public Keys查看原文 →
把密钥打印在纸上、离线保存,是可能的最安全的冷存储,因为没有任何东西接触互联网。
作者称纸钱包对大多数用户来说是过时而危险的技术:生成一个涉及微妙的陷阱,首先是生成的代码可能含有隐藏的后门,而许多比特币恰恰是这样被偷走的。恢复码和硬件签名设备是被推荐的替代品。同样的转变也解释了为什么靓号地址几乎消失了——它们与确定性备份配合得很差,而且重复使用一个地址会把支付关联起来,暴露交易对手,而不只是所有者。
“纸钱包是一种过时的技术,对大多数用户来说是危险的。”
“Paper wallets are an OBSOLETE technology and are dangerous for most users.”
Keys and Addresses › Paper Wallets查看原文 →
第 4 章的核心概念
- 密钥即所有权
- 持有私钥,才使币是你的;丢失或泄露它,就转移了这种控制。 无论格式或地址风格如何,花费的权限都来自同一把底层的 256 位私钥。
- 适用处: 控制只是密码学意义上的——如果密钥丢了,没有恢复的权威。 格式转换很简单;安全取决于那个数字,而不是它的编码。
- 椭圆曲线乘法
- 一种陷门操作:从私钥到公钥很容易,反过来不可行。
- 适用处: 安全假定今天的计算机和算法无法求解离散对数。
- 哈希承诺
- 一个简短的、固定大小的指纹,把你绑定到一个你以后可以揭示的更大的输入上。
- 适用处: 其强度只取决于哈希抵抗找到第二个匹配输入的能力。
- 地址与身份的关联
- 重复使用一个公钥,让观察者能把不同的支付关联到同一个接收者。 对许多笔支付重复使用同一个地址,会把这些支付关联起来,暴露交易对手,而不只是所有者。
- 适用处: 为每笔支付发行一个新的公钥即可避免。 对已经公开报告收入的实体也许可以容忍,但仍然会伤害付款人和收款人。
- Base58check 编码
- 一种紧凑的文本格式,加上一个版本字节和一个四字节校验和,使输错的地址被拒绝。
- 适用处: 只有 P2PKH 和 P2SH 模板使用它;它能检测错误,却无法定位错误。
- 压缩公钥
- 33 字节的密钥,只存 x 外加一个说明 y 是偶数还是奇数的前缀。
- 适用处: 同一把私钥,但承诺不同,因此地址也与未压缩形式不同。
另外 5 个概念
- 传统的支付到脚本哈希
- 一个承诺于被哈希的赎回脚本的输出,花费者之后必须揭示并满足它。
- 适用处: 输出脚本必须恰好是 OP_HASH160 <20 字节> OP_EQUAL,而且 P2SH 不一定是多重签名。
- 地址碰撞攻击
- 当攻击者影响被承诺的输入时,160 位哈希的安全性降到约 2^80。
- 适用处: 主要适用于多方创建地址;单方地址保留接近 2^160 的原像安全性。
- Bech32 地址
- 一种单一大小写、32 个符号的地址格式,既能检测,也能定位转录错误。
- 适用处: 只有当输入的地址保持原来的长度时,它的错误保证才成立。
- Bech32m 地址结构
- 一个地址由人类可读部分、分隔符“1”、一个隔离见证版本字符、一个 2-40 字节的见证程序和一个 6 字符的校验和组成。
- 适用处: 对隔离见证 v0,见证程序必须是 20 或 32 字节;v1 目前只有 32 字节。
- “压缩私钥”的误称
- “压缩私钥”不过是带一个单字节 01 后缀的 WIF 导出,说明只应从它推导出压缩公钥;密钥本身并没有被压缩。
- 适用处: 只适用于导出格式;底层的 256 位数字没有改变。
第 4 章划线与批注AI 陪读
“它不是用来“加密”(使之保密)交易的。”
“It’s not used to "encrypt" (make secret) the transactions.”
查看原文 →本章里最有用的一个纠正。大多数新手以为比特币里的密码学意味着保密;它其实是关于完全公开的账簿上不可伪造的作者身份。
“抛一枚硬币 256 次,你就得到了一个随机私钥的二进制数字”
“toss a coin 256 times and you have the binary digits of a random private key”
查看原文 →把密钥当作抛硬币记录,是个很好的祛魅,但注意作者立刻不得不用一条警告把它收回。教学法和安全建议互相拉扯。
“据估计,可见宇宙含有 10^80 个原子”
“the visible universe is estimated to contain 10^80^ atoms”
查看原文 →这个比较悄悄地拆了自己的台:10^77 是 10^80 的千分之一。本意的敬畏是真的,但所选的这把尺子,实际上让密钥空间听起来很小。
另外 17 条批注
“由美国国家标准与技术研究院(NIST)制定”
“established by the National Institute of Standards and Technology (NIST)”
查看原文 →事实上站不住脚——secp256k1 来自 SECG/Certicom,而不是 NIST,而比特币选择它而不是 NIST 自己的曲线,本身就是关于不信任标准机构的一个著名故事。
“这些技术奇妙地管用,尽管我们把兴趣限制在曲线上有两个整数坐标的点上!”
“These techniques curiously work, even though we are restricting our interest to points on the curve with two integer coordinates!”
查看原文 →作者自己的惊奇透露出来的那一句话。微积分被借来当作纯粹的形式主义,意义被剥掉,而答案仍然成立——那就是 ECC 核心的奇异之处。
“想象一下鲍勃在电话里把那个念给爱丽丝听”
“Imagine Bob trying to read that to Alice over the phone”
查看原文 →原来整章的架构,是由人的笨拙而不是数学驱动的。地址之所以存在,是因为人会输错和读错——密码学迁就手指和字体。
“出于中本聪从未说明的原因”
“For reasons Satoshi Nakamoto never stated”
查看原文 →令人耳目一新的诚实。比特币是作为一件带有未解释接缝的历史文物来教的,而不是一个干净的推导——双重哈希就是碰巧发生的事。
“base58 就是 base64 去掉 0(数字零)、O(大写字母 o)、l(小写字母 L)、I(大写字母 i)”
“base58 is base64 without the 0 (number zero), O (capital o), l (lower L), I (capital i)”
查看原文 →排版进入了协议。四个字符被排除,因为某些字体把它们渲染得很像——账簿的编码是由字母的形状塑造的。
“使用更小的公钥会得到更小的交易,从而让同一个区块里能做更多的支付。”
“Using smaller public keys results in smaller transactions, allowing more payments to be made in the same block.”
查看原文 →一位开发者多年之后注意到一种 33 字节的编码,事后让有效区块容量翻了一倍。这里的压缩不是优化细节——而是阴差阳错的货币政策。
“一把私钥可以产生以两种不同格式(压缩和未压缩)表达的公钥,它们产生两个不同的比特币地址”
“a single private key can produce a public key expressed in two different formats (compressed and uncompressed) that produce two different Bitcoin addresses”
查看原文 →作者把这一点标为“令人困惑”就继续往下讲了,但这是本章最深的一点:比特币里的身份不是密钥,而是密钥的编码。同一个秘密,两个互相够不着的余额。
“如果输出脚本不恰好是 OP_HASH160 <20 字节> OP_EQUAL,赎回脚本就不会被使用,任何比特币都可能无法花费,或者任何人都能花费”
“If the output script is not exactly OP_HASH160 <20 bytes> OP_EQUAL, the redeem script will not be used and any bitcoins may either be unspendable or spendable by anyone”
查看原文 →注意其双峰性:失败模式要么是完全损失,要么是完全送人,从不是部分的什么。P2SH 是作为模式匹配的特例嫁接上去的,而这条警告就是伤疤组织。
“比特币网络的存在证明,针对像 HASH160 这样的 160 位函数的碰撞攻击是切实可行的”
“the existence of the Bitcoin network proves that collision attacks against 160-bit functions like HASH160 are practical”
查看原文 →绝妙的修辞转折——系统的安全被用作它自身弱点的证明。挖矿是个活的基准,表明 2^80 是一个可以买到的量。
“哈希算法的强度降低到它的平方根”
“the strength of hash algorithm is reduced to its square root”
查看原文 →真正的教训不是数学,而是别人一旦帮助构造你的地址,威胁模型就变了。多方的设置悄悄让你的安全位数减半。
“人们认为,用户增删字符,不太可能产生带有有效校验和的字符串”
“it was thought that it would be very unlikely that a user adding or removing characters would produce a string with a valid checksum”
查看原文 →“人们认为”——被动语态标出了严谨让位于直觉的确切之处。一个其余部分可证明正确的设计里,唯一未经证明的假设,正是它出问题的地方。
“bech32 算法中某个常数的选择,恰好让增删字母“q”变得非常容易”
“the choice for one of the constants in the bech32 algorithm just happened to make it very easy to add or remove the letter "q”
查看原文 →一整个地址格式被一个任意的常数所破坏。而修复也是一个常数。脆弱和修复栖身于同样荒谬的微小尺度。
“有些允许用户双击一个词来高亮它以便复制粘贴的操作系统和应用,不会把高亮延伸到冒号及其之后”
“some operating systems and applications that allow a user to double-click a word to highlight it for copy and pasting won’t extend the highlighting to and past a colon”
查看原文 →密码学的格式设计,向双击文本选择的行为低头。塑造一个协议的、最微不足道的约束——也是格式成败的诚实原因。
“至关重要的是,只用校验和来检测错误——而不是纠正错误”
“it’s essential to use the checksum only for error detection—not correction”
查看原文 →较早的一段推销 bech32 “帮助纠正错误”的能力,然后这一段悄悄禁止自动纠正。这个区别——向用户展示,绝不悄悄修复——在一个括号里做着巨大的安全工作。
“人们曾希望,我们也许再也不需要经历全系统范围的升级周期”
“It was hoped that we might never again need to go through the system-wide upgrade cycles”
查看原文 →bech32 真正的设计目标不是优雅,而是逃离协调成本。在一个没有人当家的系统里,最难的工程问题是说服成千上万的钱包作者去在意。
“这将帮助你的软件在今后许多年里保持可用,即使你无法添加对新比特币特性的支持”
“This will help make your software usable for many years to come even if you aren’t able to add support for new Bitcoin features”
查看原文 →一次悄悄的坦白:大多数钱包软件都在生命中途被抛弃了。这里的向前兼容,与其说是工程上的美德,不如说是为作者自己的疏忽买的保险。
“本节的信息主要对那些需要与早期比特币钱包兼容的人有意义。”
“The information in this section is mainly of interest to anyone needing compatibility with early Bitcoin wallets.”
查看原文 →书一直在教已经死掉的格式,然后为此道歉。诚实,但它揭示了一个永远不能删除任何东西的系统所缴纳的税。
读后感AI 陪读
比特币的数学很优雅,它真正的麻烦从人开始
第4章以爱丽丝需要付钱给鲍勃开篇,以纸钱包被宣告死亡结束,而这两点之间的距离就是整个论证:它从数学开始,以一部编码的社会史告终。弧线干净得可以用一行话说完——随机性变成私钥,单向的椭圆曲线乘法变成公钥,脚本取代密钥的位置,哈希把密钥缩成地址,编码给地址穿上适合人手的衣裳。但本章真正的主题,只有在你注意到哪一步干的活最多之后才浮现出来。密码学是最优雅的部分,也是麻烦最少的部分;本章每一个真正的困难,都出现在数学做完之后,出现在数字遇上手指、字体、电话和双击的那一层。
最有价值的一个纠正出现得很早:这种密码学并不让任何东西成为秘密。在一本按设计就是公开的账簿上,被保护的不是机密性,而是作者身份——对完全可见的事实做出不可伪造的签名。几乎每个新手的心智模型都把这一点颠倒了,而本章把第一口气花在这上面是对的。从这里起,教学法是刻意朴素的:私钥是 256 次抛硬币的记录。这个意象美妙地祛魅,却立刻被一条安全警告收回,而这种张力——教的时候当作简单,同时警告说它并不简单——贯穿全章。本章对理解一件事与有能力去做这件事之间的差距是诚实的。
继续阅读
我要反驳的是本章对敬畏的本能。把密钥空间与可见宇宙中的原子相比,本意是压倒读者,但 10^77 对 10^80,悄悄让这个数字听起来很小;这把尺子削弱了它被选来要证明的观点。把 secp256k1 归于 NIST 就是错的——它来自 SECG/Certicom,而比特币有意避开 NIST 自己的曲线,是关于不信任标准机构的较有名的故事之一,所以这个错误抹掉了某些历史上有趣的东西。与此相对,真正的思想诚实的时刻格外醒目:作者明显流露出的惊奇——由微积分推出的切线规则,在剥去连续性、被限制在曲线上的整数点之后,居然还管用。那才是 ECC 核心真正的奇异之处,看到它被点出来而不是被抹平,很好。
本章最深的洞见,被它仅仅标为“令人困惑”,然后就抛在脑后了:一把私钥,两种公钥编码,两个地址,两个余额。比特币里的身份不是密钥——而是密钥的编码。下游的一切,都出自对这一点的认真对待。一位开发者后来才意识到,公钥可以存成 33 字节而不是 65 字节,这在事后扩大了有效的区块容量;看似编码优化的东西,原来是阴差阳错的货币政策。Base58 排除了四个字符,因为字体把它们渲染得很像;bech32 里的分隔符不是冒号,因为双击选择在冒号处就会停下。排版和文本选择的行为,是密码学协议里承重的元素。本章没有完全大声说出这一点,但证据在页面上随处可见。
安全方面的内容是文字最锋利的地方。用挖矿网络的存在来证明 2^80 的工作量是可以买到的——把系统的强大当作它自身弱点的证据——真是一个相当漂亮的修辞动作,而它底下的抗碰撞性教训,比算术更要紧:别人一旦帮助构造你的地址,你的有效安全就减半,而多方的设置会悄悄改变威胁模型。同样有启发的是 P2SH 的警告,那里的失败模式是双峰的:币要么任何人都花不了,要么所有人都能花,从不是部分的什么。这是一个被当作模式匹配的特例嫁接上去的功能所留下的伤疤组织。
bech32 的插曲是本章最好的寓言,而它的措辞已经把底牌亮了出来。“人们认为”增删字符不太可能产生有效的校验和——被动语态标出了证明让位于直觉的确切之点——而恰恰是这一个未经证明的假设,让设计出了问题,大约围绕着字母“q”。一整个地址格式,被一个任意的常数所破坏,又被一个任意的常数所修复。脆弱和修复都栖身于同样荒谬的微小尺度。还要注意随后划出的那条小心的线:校验和用于检测,绝不用于悄悄纠正。较早的一段宣传帮助用户修正错误;这一段则禁止替他们这么做。向用户展示,绝不悄悄改写——大量的安全承载在这个区分之中,它值得的不只是一个括号。而这一切背后的动机从来不是优雅。Bech32m 向前兼容的见证版本,是为了逃离协调成本而存在的:在一个没有人当家的系统里,最难的工程问题是说服成千上万个独立的钱包作者去升级。那条建议——支持未来的版本,这样你的软件“即使你无法添加对新比特币特性的支持”也仍然有用——是一次悄悄的坦白:大多数钱包软件都在生命中途被抛弃了。
那么该对读者说什么呢。第一,把数学学一遍,然后接受这一点:编码才是你真正会赚钱或亏钱的地方——对一个输错的地址做出的正确签名,是对一个不可逆的错误的完美证明。第二,把“出于中本聪从未说明的原因”读作本章诚实的语域:比特币是作为一件带有未解释接缝的历史文物来教的,而不是一个干净的推导,而双重哈希就是碰巧发生的事。第三,别怨恨地略过那些过时的章节。书一直在教已经死掉的格式,并为此道歉,而这反复的道歉本身就是教训:一个永远不能删除任何东西的系统,在每一次解释、每一个钱包、每一位读者的注意力里,都要缴纳永久的税。本章的标题许诺的是密钥和地址。它实际交付的,是证明密码学是容易的那一半,而持久的困难在于,让不可伪造的数学,经受住与人手和不协调的软件的接触而存活下来。
在 FeedLitra 里读第 4 章,每段旁边都有这些卡片。
开始读书第 5 章:钱包恢复
BIP32 究竟是如何从父链码推导出子密钥的?
第 5 章是怎样展开的AI 辅助
开篇——被框定为恢复、而非失窃的问题。 本章以一个严峻的前提开篇:丢失的私钥就是丢失的钱,所以钱包设计其实是防止数据丢失变成财务损失的学问。它重建了通往这里的历史。在最早的钱包里,每把密钥都是独立生成的,这意味着每一把新密钥——大约再多三十二个字节加上开销——都迫使用户重做备份。漏掉一把,那些币就没了。作者指出了这造成的反常激励:与其不断备份,一些用户干脆重复使用单一地址,用隐私换便利。这条死胡同引出了本章其余部分所审视的解决办法。
展开——种子及其局限。 确定性生成直接回答了这个问题:一个随机种子,经过一套可重复的过程,永远重新长出同样的密钥序列,所以单次备份就覆盖了无限多把密钥。作者用一个 shell 示例演示,把种子与计数器一起哈希,重现出相同的推导值,同时指出它只是个说明,而不是真正的 BIP32 数学。但随后是本章核心的限定:种子是必要的,却不是充分的。恢复还需要路径信息,也需要完全存在于协议之外的数据。鲍勃选的地址标签、爱丽丝写的付款备注——这些只存在于他们各自的钱包文件里,所以仅用种子来恢复,会把钱还给你,却带着一个空白的说明字段,就像一份去掉了商家名称的、一年前的银行对账单。加密的自动数据库备份作为部分补丁被提出。种子本来要关上的备份问题,悄悄地又重新打开了。
转折——隐含的便利对显式的记录。 路径问题把本章分成两种办法。标准化的路径隐含地提供信息:BIP44 为 P2PKH 密钥固定了 m/44'/0'/0',符合标准的钱包在恢复之后直接重用它,免去了用户任何记录工作。代价是缺乏灵活性。恢复现在取决于钱包猜对了标准,而且因为像 BIP39 和 SLIP39 这样的码不带版本号,悄悄丢掉或增加所支持路径的软件,没有办法警告任何人。作者随后用一个隐含路径根本处理不了的案例,反转了便利的论证:在 2-of-3 多重签名的安排中,爱丽丝只是为了定位联合资金,就需要全部三位参与者的公钥,所以每一方都必须备份全部三个——这是任何标准化路径都无法重新生成的信息。这个论证,把高级的设置推向了描述符,它显式地记录路径和脚本。
详述——机制暴露什么,又隐瞒什么。 确立了恢复的框架之后,本章走遍 BIP39/BIP32 这套栈及其对暴露的后果。先是词语码和 PBKDF2 推导的种子、熵的大小,以及可选的密码短语;然后是扩展密钥,一把密钥与它的链码配成一对,恰恰是允许推导子密钥的东西。向公钥加上一个公开的调整量,不用私钥就产生子公钥,这使仅观察的运作成为可能:一台暴露在互联网上的商店服务器,可以只持有一个 xpub,为每个订单铸造一个新地址,而身上仍然没有任何可花费的东西——而一把剥掉了链码的子密钥,不会暴露任何兄弟密钥。硬化推导堵上了链码泄露的路径,而 BIP43/44 为路径树强加了秩序。与这些便利相对,作者摆出了间隔上限,抽象在这里明显吃力:一个恢复或同步的钱包,在连续一段固定数量的未使用密钥之后就停止搜索,所以超出这一段的支付是看不见的。因此,一个繁忙的接收者面临三个糟糕的选项——拒绝请求,推导超过上限而冒着资金没有任何钱包能找到的风险,或者重复使用旧密钥而放弃隐私。
收尾——责任在用户。 本章以拓宽主张结束:数据丢失,而非失窃,很可能是永久丢失比特币的最大原因,因为密钥和支撑数据都没了的币,就是无法花费。离场时纠正了两个误读。写下来的恢复词并不是完整的备份——它们恢复密钥,别的什么都不恢复,让标签和共同签名者的公钥处于无保护状态,这是描述符式显式备份长期以来的理由。而背下这些词也不是安全的选择:只靠记忆的存储,冒着全部丢失的风险,什么也不给继承人留下,胁迫是有记录的(作者引用了詹姆森·洛普记录的针对疑似比特币持有者的一百多起人身攻击,其中至少三起导致死亡),而被遗忘的可选密码短语会悄无声息地失败,因为没有任何密码短语会被拒绝为错误。在审视了为防止丢失而建立的系统之后,作者把剩下的义务端端正正地放在用户身上:做好备份,并且测试它们。
关键论点,以及支撑它们的原文
当钱包独立生成每一把密钥时,用户每有一把新密钥就得重做备份,这使得最终丢失几乎不可避免。
作者指出,每一把独立生成的密钥,都意味着要多备份大约 32 个字节加上开销,而没能及时备份就会丧失对那些币的访问——这种压力驱使一些用户退回到重复使用单一密钥,毁掉了他们的隐私。
“未能及时备份钱包数据库,会导致用户无法访问那些发给尚未备份的密钥的任何资金。”
“Failure to back up the wallet database on time would lead to the user losing access to any funds received to keys that had not been backed up.”
Wallet Recovery › Independent Key Generation查看原文 →
确定性生成通过把无限多把密钥压缩成一个备份的种子,修复了这一点——直接回答了前面的问题。
作者把旧制度与新制度对比:既然所有密钥都按固定的过程出自种子,用户就可以对整个钱包只备份一次。一个把种子与计数器一起哈希的 shell 演示表明,推导出的值可以被完全重新生成,尽管作者指出它只是说明性的,而不是真正的 BIP32 算法。
“使用确定性密钥生成的用户,只需记录他们的种子和所用确定性算法的引用,就可以备份钱包里的每一把密钥。”
“A user of deterministic key generation can back up every key in their wallet by simply recording their seed and a reference to the deterministic algorithm they used.”
Wallet Recovery › Deterministic Key Generation查看原文 →
拥有种子是必要的,但不是充分的,这重新打开了种子本该关上的备份问题:标签和其他存在于协议之外的数据,无法从它推导出来。
作者的案例:鲍勃选的地址标签和爱丽丝写的付款标签,只存在于他们各自的钱包文件里,所以仅从种子恢复,会把钱带回来,却带着空白的说明字段——就像读一份去掉了商家名称的、一年前的银行对账单。加密的自动数据库备份作为部分补救被提出。
“然而,由于地址和交易标签只存储在每个用户的钱包数据库里,而且它们不是确定性的,只用恢复码是无法恢复它们的。”
“However, because address and transaction labels are stored only in each user’s wallet database and because they aren’t deterministic, they can’t be restored by using just a recovery code.”
Wallet Recovery › Backing Up Nonkey Data查看原文 →
另外 3 个论点
让软件假定标准化的路径,免去了用户任何记录工作,但代价是缺乏灵活性:钱包必须在几条路径之间猜测,而不带版本的码在猜测改变时无法警告任何人。
作者的例子是 BIP44 把 m/44'/0'/0' 固定为 P2PKH 密钥的路径,符合标准的钱包在恢复之后直接重用它——方便,然而这意味着恢复取决于钱包试对了标准。而因为像 BIP39 和 SLIP39 这样的码不带版本号,悄悄丢掉或增加所支持路径的软件,没有办法告诉用户。
“隐含脚本的缺点是缺乏灵活性。”
“The disadvantage of implicit scripts is their inflexibility.”
Wallet Recovery › Backing Up Key Derivation Paths查看原文 →
把便利的论证反过来,隐含路径无法恢复特定于单个用户的数据,所以高级脚本把备份推向记录路径和脚本的显式描述符。
作者的多重签名案例:在 2-of-3 的安排中,爱丽丝只是为了定位联合资金,就需要全部三位参与者的公钥,所以每一方都必须备份全部三个——这是任何标准化路径都无法重新生成的信息。
“随着多重签名和其他高级脚本在比特币上变得越来越普遍,隐含路径的不灵活变得越来越重要。”
“As multisignature and other advanced scripts become more common on Bitcoin, the inflexibility of implicit paths becomes more significant.”
Wallet Recovery › Backing Up Key Derivation Paths查看原文 →
在本章结尾,作者论证说,数据丢失而非失窃,很可能是永久丢失比特币的最大原因。
推理是这样的:如果花费所需的密钥和其他数据都没了,这些币就无法花费,而本章在审视了为防止这种情况而建立的钱包系统之后,作者强调,真正使用它们——做好并测试备份——的责任,落在用户身上。
“如果花费你比特币所需的密钥和其他必要数据丢失了,那些比特币将永远无法花费。”
“If the keys and other essential data required to spend your bitcoins is lost, those bitcoins will forever be unspendable.”
Wallet Recovery › Using an Extended Public Key on a Web Store查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
一个种子重新长出每一把密钥
单个随机种子,经过一个可重复的算法,永远重现同样的密钥序列,所以用户一次备份种子,而不是每把新密钥都备份。作者用一个 shell 示例来说明,把种子与计数器一起哈希,重新生成相同的推导值,并指出它只是模仿真正的 BIP32 数学。
机制 2
仅观察的地址生成
一把密钥加上它的链码(一个扩展密钥),才让子密钥可以被推导,而向公钥加上一个公开的调整量,不用私钥就产生子公钥。所以一台暴露在外、只装了一个 xpub 的商店服务器,可以为每个订单铸造一个新地址,而身上没有任何可花费的东西,而一把没有链码的子密钥,不会暴露任何兄弟密钥。
机制 3
为什么间隔上限会咬人
一个恢复或同步的钱包,在连续一段固定数量的未使用密钥之后就停止寻找,所以付给超出这一段的密钥的款项是看不见的。因此,一个繁忙的接收者会撞上天花板,必须要么拒绝请求,要么推导超过上限而冒着看不见资金的风险,要么重复使用旧密钥而失去隐私。
常见误读
“我把恢复词写下来了,所以我的钱包已经完全备份了。”
恢复码恢复密钥,别的什么都不恢复。地址和交易标签只存在于你自己的钱包文件里,而在像 2-of-3 多重签名这样的共享设置里,你仅仅为了找到资金,还需要其他参与者的公钥——所有这一切都需要它自己的备份,这就是为什么存在描述符式的显式备份。
“然而,由于地址和交易标签只存储在每个用户的钱包数据库里,而且它们不是确定性的,只用恢复码是无法恢复它们的。”
“However, because address and transaction labels are stored only in each user’s wallet database and because they aren’t deterministic, they can’t be restored by using just a recovery code.”
Wallet Recovery › Backing Up Nonkey Data查看原文 →
“词语就是用来背的,所以只把恢复码记在脑子里是最安全的选择。”
能够幸存下来的,是书面的或其他实体的备份:只靠记忆的存储,冒着全部丢失的风险,什么也不给继承人留下,而胁迫是有记录的现实——作者引用了詹姆森·洛普记录的针对疑似比特币持有者的 100 多起人身攻击,其中至少三起导致死亡。被遗忘的可选密码短语同样悄无声息地失败,因为没有任何密码短语会被拒绝为错误。
“在本节中,我们将看几种恢复码,它们旨在让备份更容易、更安全。”
“In this section, we’ll look at several recovery codes, which are intended to make backups easier and safer.”
Wallet Recovery › Seeds and Recovery Codes查看原文 →
第 5 章的核心概念
- 确定性密钥生成
- 一个随机种子加一个可重复的算法,重新生成每一把密钥,所以只需要备份种子。
- 适用处: 只保护密钥;标签之类的非确定性数据无法从种子中恢复。
- 公开子密钥推导
- 向公钥加上一个公开的调整值,不触碰私钥就产生子公钥。
- 适用处: 花费仍然需要父私钥的持有者来应用同样的调整。
- 分层确定性(HD)密钥生成
- BIP32 把一个种子变成一棵无限的密钥树,其分支可以带有组织上的含义。
- 适用处: 这棵树大得根本无法盲目扫描,所以推导路径也必须被记录下来。
- 恢复码
- 种子的一种人类可读的编码,通常是词语,意在让备份更容易、更安全。
- 适用处: 只靠记忆的存储,有全部丢失、继承失败和人身胁迫的风险。
- 隐含路径
- 钱包假定使用由 BIP 定义的标准化推导路径,所以用户除了恢复码,什么也不用存。
- 适用处: 对非确定性的、用户特有的数据(比如其他签名者的公钥)会失效。
- 显式路径
- 备份记录哪些路径和脚本对应哪些密钥,通常是以输出脚本描述符的形式。
- 适用处: 需要备份额外的数据,这些数据没那么秘密,但仍需要隐私保护。
另外 6 个概念
- BIP39 恢复码
- 12-24 个随机生成的词语,编码 128-256 位的熵,由 PBKDF2 拉伸成 512 位的种子。
- 适用处: 不是脑钱包;词语是机器选的,而它的密钥拉伸参数按现代标准是弱的。
- 扩展密钥
- 一把密钥加上它的链码,推导子密钥所需的那一对;以 base58check 编码为 xprv 或 xpub。
- 适用处: 扩展公钥只推导公钥,不能花费资金。
- 可选的 BIP39 密码短语
- 一个额外的、要记忆的因素,使同一个恢复码变成不同的种子。
- 适用处: 任何密码短语都不会是错的,所以被遗忘的密码短语会悄悄丢掉资金。
- 间隔上限
- 钱包在停止寻找后面的支付之前,容忍连续多少个未使用的密钥。
- 适用处: 只在从同一个扩展公钥恢复或同步另一个钱包时才有关系。
- 硬化子密钥推导
- 从父私钥推导子链码,使一把泄露的子密钥不能暴露兄弟密钥或父密钥。
- 适用处: 硬化分支不能只从 xpub 推导,所以用在共享 xpub 的层级之上。
- HD 钱包密钥路径
- 一种用斜杠分隔的命名约定,标识每把密钥自主密钥以来的祖先关系。
- 适用处: BIP44 固定五个层级;其他用途使用不同的第 1 层索引。
第 5 章划线与批注AI 陪读
“未能及时备份钱包数据库,会导致用户无法访问那些发给尚未备份的密钥的任何资金”
“Failure to back up the wallet database on time would lead to the user losing access to any funds received to keys that had not been backed up”
查看原文 →早期的设计悄悄地惩罚了良好的隐私卫生——每一个新地址都是一项新的负担。对确定性为什么不只是便利,这是个优雅的解释。
“她以后为了恢复对这些比特币的访问而需要备份的,只有”
“all she needs to back up in order to later recover access to those bitcoins is”
查看原文 →一百万个地址坍缩成 32 个字节,是本章真正的魔术。值得停下来想想,有多少风险也坍缩到了同样这 32 个字节里。
“他可以向公钥加上任何值,产生一个推导出的子公钥”
“he can add any value to the public key to produce a derived public child key”
查看原文 →这是整章的铰链:秘密和地址被解耦,这才使硬件签名器成为可能。
另外 17 条批注
“詹姆森·洛普记录了针对疑似比特币持有者的 100 多起人身攻击”
“Jameson Lopp has documented over 100 physical attacks against suspected owners of bitcoin”
查看原文 →威胁模型突然离开了密码学,变成了一根撬棍。值得注意的是,作者们让人的身体进入了一章关于密钥管理的内容。
“为合理的可否认性而设计,意味着没有办法向攻击者证明你已经透露了你所有的信息”
“Designing for plausible deniability means there’s no way to prove to an attacker that you’ve revealed all of your information”
查看原文 →这里最尖锐的一句话:保护你免受小偷的特性,把你送给了严刑拷打者。不可证伪是双向的。
“想象一下回顾一份一年前的银行或信用卡对账单,上面列有每笔交易的日期和金额,但“说明”字段是空白的”
“Imagine reviewing a bank or credit card statement from a year ago that had the date and amount of every transaction listed but a blank entry for the "description" field”
查看原文 →漂亮的一招——一章抽象的内容里唯一一个具体的类比,它之所以落地,是因为它把“恢复”重新框定为意义,而不只是金钱。
“一个丢掉了对旧路径支持的新版本钱包应用,在恢复过程中无法警告用户”
“a new version of a wallet application that drops support for an older path can’t warn users during the restore process”
查看原文 →隐含的路径夹带了一个对软件历史的隐藏依赖。种子是永恒的;围绕它的惯例悄悄地腐烂。
“主要区别在于,脑钱包由用户选择的词语组成,而恢复码是由钱包随机创建的”
“The primary difference is that a brainwallet consists of words chosen by the user, whereas recovery codes are created randomly by the wallet”
查看原文 →整个安全模型取决于不信任用户的想象力。直白而正确:人类无法做到随机。
“BIP39 的参数,即使在近十年前首次发布时,按现代标准也被认为很弱”
“BIP39’s parameters were considered weak by modern standards even when it was first published almost a decade ago”
查看原文 →难得一见的时刻:作者们批评了他们刚刚作为整套栈推荐的这个标准。诚实,也告诉你真正的约束是廉价的硬件 CPU,而不是密码学。
“使用超过 128 位的熵没有明显的好处”
“there’s no apparent benefit to using more than 128 bits of entropy”
查看原文 →祛魅落地了:512→256→128 的链条表明,每多出来的一位都被下游最弱的一环吞掉了。过了这一点,更多的熵就是演戏。
“本质上,没有“错误”的密码短语。所有密码短语都是有效的,它们都通向不同的种子”
“Essentially, there is no "wrong" passphrase. All passphrases are valid and they all lead to different seeds”
查看原文 →优雅而可怕。没有错误消息,就没有反馈——一个打错的字,悄悄地交给你一个空钱包,而不是拒绝你。
“如果钱包所有者丧失行为能力或已经死亡,而又没有其他人知道密码短语,种子就毫无用处”
“If the wallet owner is incapacitated or dead and no one else knows the passphrase, the seed is useless”
查看原文 →书把死亡悄悄放进了威胁模型。自我保管意味着,你自己的死亡是一个你没法同时防两次的攻击者。
“一把泄露的子私钥,连同父链码,就暴露了所有子密钥的全部私钥。”
“A single leaked child private key, together with a parent chain code, reveals all the private keys of all the children.”
查看原文 →所以,拯救了加布里埃尔网店的那个 xpub 的便利,与一把子密钥一旦漏出去就会引爆一切的,是同一个东西。本章为这个功能铺垫了好几页,然后才展示导火索。
“连续多少个未使用的密钥无法收到付款而又不引起问题的最大数量,称为间隔上限(gap limit)”
“The maximum number of unused keys in a row that can fail to receive a payment without causing problems is called the gap limit”
查看原文 →一种美妙而平凡的失败模式:隐私的破裂不是因为密码学,而是因为顾客放弃了他们的购物车。
“还有人提出了其他解决办法,比如要求花费者的钱包构造(但不广播)一笔交易”
“Other solutions have been proposed, such as asking the spender’s wallet to construct (but not broadcast) a transaction”
查看原文 →承认这一切都没有在生产中使用,是那一节里信息量最大的一句话——一个未解决的问题,打扮成了脚注。
“建议使用字母 h”
“using the letter h is recommended”
查看原文 →整个记号约定,被 shell 会吃掉撇号这个事实所扭曲。密码学向命令行低头。
“一把密钥的“祖先”是从右往左读的”
“The "ancestry" of a key is read from right to left”
查看原文 →亲属关系的语言在这里做了实事——但注意方向:你读的是倒着的血统,从子读到根。这恰恰也是恢复的工作方式。
“这棵树可以有你想要的那么深,有无限多代。”
“The tree can be as deep as you want, with an infinite number of generations.”
查看原文 →两句话之后,这种无边的自由就被点名为问题。没有共同约定的地址,无限的空间毫无用处。
“HD 钱包应当只使用这棵树的一个第 1 层分支”
“an HD wallet should use only one level-1 branch of the tree”
查看原文 →对无限的修复是自愿的自我限制。BIP43 不增加能力,它减去能力——而这就是全部的价值。
“而之前的层级使用了硬化推导,这一层使用普通推导”
“whereas the previous levels used hardened derivation, this level uses normal derivation”
查看原文 →铠甲上一个有意留下的裂缝:这里用普通推导,这样仅观察的服务器可以看到你的地址,而不必持有密钥。安全被精确地交易掉,而不是草率地。
读后感AI 陪读
每个钱包方案都从一个问题里解救出来,又造出下一个问题
第5章的结构是一段不断发现救援有代价的救援叙事。它以比特币最直白的事实开篇——丢了密钥,就丢了币——然后把钱包的历史当作一系列的逃脱走过一遍:从 JBOK 钱包,其不断备份的要求悄悄地惩罚了任何践行良好地址卫生的人,到确定性种子,到分层树,再到基于词语的恢复码。这条弧线看起来像是稳步的进步,而本章第一个真正的魔术,是看着一百万个地址坍缩成 32 个字节。但本章足够诚实,表明同样的坍缩把所有的风险都集中到了同样这 32 个字节里,而这个模式——每一份便利都带着它自己的导火索——重复得如此一致,以至于它成了本章实际的论证。
技术的脊梁是 BIP39/BIP32/BIP44 这一套栈,而作者们出奇地愿意削弱他们自己推荐的标准。BIP39 的 PBKDF2 参数被指出即使在发布时也很弱——真正的约束是廉价的硬件 CPU,而不是密码学。超过 128 位的熵被表明是演戏,被 512→256→128 链条下游最弱的一环吞掉了。可选的密码短语既优雅又可怕:没有“错误”的密码短语,意味着没有错误消息,所以输错一个字,得到的是一个悄无声息的空钱包,而不是一次拒绝,而如果所有者带着脑子里的密码短语死去,种子就是废品。最后一点,是本章做了一件密钥管理文章很少做的事:它让死亡和人的身体进入了威胁模型——洛普记录的一百多起人身攻击,以及那个毁灭性的观察:合理的可否认性,这项能打败小偷的特性,恰恰是把你送给严刑拷打者的东西,因为不可证伪是双向的。
继续阅读
整章的铰链是公钥推导——不用私钥就能延伸一个公钥。秘密与地址的这一次解耦,使硬件签名器、仅观察的服务器,以及加布里埃尔那个由 xpub 驱动的网店成为可能。然后,几页之后,本章把它引爆:一把泄露的子私钥加上父链码,就暴露了每一个兄弟密钥。硬化推导就是补丁,而 BIP44 在账户层面有意使用普通推导,被表明是一笔精确定价的交易,而不是粗心的做法——有意花掉安全,买来仅观察的可见性。
更安静、更有趣的失败,存在于实用的章节里。隐含的标准路径恢复,夹带了一个对软件历史的隐藏依赖:种子是永恒的,但包裹在它周围的惯例会腐烂,而一个丢掉了旧路径的钱包,在恢复期间甚至无法警告你——这是描述符最好的理由。间隔上限(gap limit)是一次美妙而平凡的崩溃,隐私不是败给了密码学,而是败给了放弃购物车的顾客,而那一节里信息量最大的一句话,是承认所提议的修复办法没有在生产中使用——一个未解决的问题,打扮成了脚注。非密钥数据的讨论,凭本章唯一一个具体的类比赢得了它的位置:一份一年前的银行对账单,每笔金额都完好无损,每条说明都是空白,这把恢复重新框定为意义的恢复,而不只是金钱的恢复。就连记号也带着一个教训——硬化推导写作 h,因为 shell 会吃掉撇号,密码学向命令行低头。而这棵树夸耀的无限深度,在被提出的两句话之后就被点名为一项负担:BIP43/44 的价值是减法性的,在一个大得无法搜索的空间上施加共同约定的结构。
我要对读者说的是:别把它读成一章如何备份的指南。把它读成一章关于种子短语究竟是什么的内容——一个你自愿建起的单点故障,由你无法控制的惯例来防御,守护着你将需要去解释、而不仅仅是拥有的信息。像本章教你的那样读密钥的祖先关系,从右往左,从子回到根;那种倒着的阅读,恰恰就是恢复。然后问本章提出却无法回答的问题:除了你,还有谁真能完成这一趟遍历。
在 FeedLitra 里读第 5 章,每段旁边都有这些卡片。
开始读书第 6 章:交易
RBF 如何决定哪笔相互冲突的交易获胜?
第 6 章是怎样展开的AI 辅助
开篇。 本章一开始,是替换一种直觉,而不是介绍一个字段。作者坚持说,发送比特币不是交出一个数字对象;而是让一本共享账簿记录下新的所有者。土地登记簿的比较承载着这一点:爱丽丝不能把一块地实体地递给鲍勃,她是说服政府更改登记簿上的名字。一笔交易,就是同时在每个全节点上执行那番说服的数据——这就是为什么输入只不过是通过交易 ID 和索引指回先前的一个输出,并声称其中记录的币。框架定好之后,本章承诺了它的组织手段:取一笔序列化的交易,按顺序逐字节走一遍。版本最先出现,而这一走已经一箭双雕,因为版本字段被解释为不是一个标签,而是一道防护:新的共识规则可以只限定于更高的版本号,使很久以前签名的交易仍然有效。作者指出这并非假设:闪电网络依赖于广播之前很久就已签名的交易,所以任何在 BIP68 之前预签名的人,本应选择一个保留该特性的版本,而且只有设计者避开为未来升级预留的字段时,这种保护才成立。
展开。 从这里起,剖析逐字段进行:隔离见证的标记和标志,然后是输入列表,带着它的出点、输入脚本和序列号。序列号是描述性的巡礼第一次展开成历史的地方。它最初的用途——靠增大数字来替换一笔交易——被拆解成一个建立在策略、运气和别人带宽上的破碎设计:没有什么迫使矿工偏爱序列号更高的版本,而成本的不对称是毁灭性的,每分钟 1000 次替换、每次 200 字节,让发送者花费约 20 KB,却给大约 50000 个中继节点强加了大约 10 GB。这个失败解释了这个字段目前的双重生活:作为 RBF 信号,以及对版本 2 或更高的交易来说,作为相对时间锁。输出遵循同样的“字段加理由”的模式:先是金额,然后是粉尘上限,作者小心地把它归为中继与挖矿策略而不是共识,满是坦率地说任意的数字,比如常见的 546 聪下限。它的目的不是阻止用户浪费他们自己的钱,而是保护运行全节点的人,因为价值低于花费它所需手续费的输出,永远不会被花掉,永久地驻留在每个人都必须追踪的 UTXO 集里——这恰恰就是为什么不可花费的 OP_RETURN 数据输出可以豁免。然后是输出脚本,巡礼在此停顿。
转折。 本章的支点随着见证的概念到来,在那里,编目让位于格式本身制造的问题。因为交易 ID 是对输入脚本计算出来的,授权数据改变了它所授权的东西的名字。作者在最小的尺度上让这一点变得具体:即便是压入数字 2,也容许好几种编码,每一种产生一笔具有不同 ID 的冲突交易,而签名的随机性让共同签名者能产生一个不同但有效的签名,悄悄地让一笔预签名的退款成为孤儿。任何已签名的子交易都指向一个不再存在的 ID,所以预签名交易的链条无法做到无需信任——爱丽丝和鲍勃甚至无法构造后续交易,直到双方的签名都固定下来。隔离见证被呈现为答案,而本章论证的分量,落在它是如何作为软分叉而不是硬分叉发布的上面。由一个 0 到 16 的数字,后接 2 到 40 字节数据组成的输出脚本,在旧规则下本来就可以用空的输入脚本花费;新节点把同样的字节重新读作见证版本和见证程序,要求授权数据放在单独的见证结构里,并把它排除在 txid 之外。作者在这里先行打消了自然的警觉:这并不意味着有人真能把币拿走,也不意味着旧节点以某种方式检查了见证。这两类节点只是行为不同——升级后的节点执行见证程序,并要求输入脚本为空,旧节点只是允许输入脚本为空,而不检查任何东西——因为新规则只禁止旧规则所允许的,网络现在执行的更严的规则,就是保护这些钱的东西。
收尾。 其余的字段随后依次打发。锁定时间完成了狭义的序列化。币基交易被处理为有意的例外:由矿工创建,带一个空出点,一个自由格式的币基字段代替输入脚本,在成熟规则之下支付补贴加手续费。度量系统接下来登场,而本章在这里是把它的线索收拢起来,而不只是增加一个话题。每个字段的字节数乘以一个特定于字段的因子,对照四百万权重的区块上限,四个权重对应一个 vbyte,而作者用软件本身核对了手算——比特币核心报告爱丽丝的交易是 569 权重,与逐字段的算术吻合。这些因子并非中立的簿记:它们被选来使花费一个现有输出所需的字段分量很轻,使币的合并变得便宜,而那些永远不会被赎回的微小输出则相对昂贵。这就把在粉尘上限处打开的圈闭合了,给同一个 UTXO 卫生的关切,一个共识层面的价格,而不是策略层面的拒绝。对没有见证结构的交易的传统序列化的简短处理,结束了本章——给读者留下了两种格式,更重要的是,留下了每个字段为什么长成这个样子的理由。
关键论点,以及支撑它们的原文
发送比特币意味着让一份共享的所有权记录得到更新,而不是把一个数字对象交给某人。
作者拿土地作比:爱丽丝并不是把一块地实体地递给鲍勃,而是说服政府更改登记簿上的名字。交易的运作方式相同,因为输入只是通过交易 ID 和索引指回先前的输出,以声称其中记录的币。
“相比之下,比特币既不以实体形式存在,也不作为数字数据存在——爱丽丝不能把一些比特币递给鲍勃,或通过电子邮件发送出去。”
“By comparison, bitcoins don’t exist either physically or as digital data—Alice can’t hand Bob some bitcoins or send them by email.”
Transactions查看原文 →
版本字段的存在,是为了让新增的共识规则不破坏很久以前签名的交易。
新规则可以被做成只适用于更高的版本号,而不触动较旧的。作者指出这并非假设的担忧:诸如闪电网络这样的协议,依赖于广播很久之前就已签名的交易,所以任何在 BIP68 之前预签名的人,本应使用一个保留该特性的版本。只有设计者远离为未来升级预留的特性,这种保护才成立。
“任何在 BIP68 之前创建预签名交易的人,本应使用版本 1 的交易,所以仅对版本 2 或更高的交易应用 BIP68 对序列号的额外约束,应该不会使任何预签名交易失效。”
“Anyone creating presigned transactions prior to BIP68 should have been using version 1 transactions, so only applying BIP68’s additional constraints on sequence to transactions v2 or higher should not invalidate any presigned transactions.”
Transactions › Version查看原文 →
纯粹靠增大序列号来替换一笔交易,是一个破碎的设计,建立在策略、运气和对别人带宽的免费使用之上。
没有什么迫使矿工尊重序列号更高的版本,而中继这些替换,对发送者几乎不花什么,对网络却代价高昂:作者计算,每分钟 1000 次替换、每次 200 字节,对攻击者约为 20 KB,但按撰写时大约 50000 个中继节点算,全网约要 10 GB 带宽。这个失败,就是该字段被重新用作 RBF 信号、并对版本 2 或更高的交易用作相对时间锁的原因。
“第一,用序列号更高的交易替换序列号更低的交易的规则,只是软件策略的问题。”
“The first was that the rules for replacing a lower-sequence transaction with a higher-sequence transaction were only a matter of software policy.”
Transactions › Sequence查看原文 →
另外 3 个论点
把输入脚本折进交易 ID,使无需信任的预签名协议成为不可能。
作者表明,即便是像数字 2 这样微不足道的值,也可以用好几种不同的编码压入,每一种产生一笔具有不同 ID 的冲突交易,而签名的随机性让共同签名者能产生一个不同但有效的签名,悄悄地使预签名的退款失效。所以爱丽丝和鲍勃甚至无法构造后续交易,直到双方的签名都已固定。
“这意味着在 Tx0 的两个签名都已知之前,爱丽丝和鲍勃无法构造 Tx1——但如果他们知道 Tx0 的签名,其中一方可以在签署退款交易之前广播那笔交易,从而消除退款的保证。这是一个循环依赖。”
“That means there’s no way for Alice and Bob to construct Tx~1~ until both signatures for Tx~0~ are known—but if they know the signatures for Tx~0~, one of them can broadcast that transaction before signing the refund transaction, eliminating the guarantee of a refund. This is a circular dependency.”
Transactions › Circular Dependencies查看原文 →
隔离见证可以作为软分叉而不是硬分叉发布,办法是复用任何人都可花费的脚本,外加一个新字段。
这是作者对刚刚所述的延展性问题的回答。由一个 0 到 16 的数字,后接 2 到 40 字节数据组成的输出脚本,在旧规则下本来就可以用空的输入脚本花费,所以旧节点继续接受这样的花费,而新节点把同样的字节读作见证版本和见证程序,要求授权数据放在单独的见证结构里。
“隔离见证的软分叉做法,基于任何人都可花费的输出脚本。”
“The soft fork segwit approach is based on anyone-can-spend output scripts.”
Transactions › Segregated Witness查看原文 →
权重系统的乘数并非任意的簿记;它们被调校得使花费现有输出变得便宜,并不鼓励创建不值得花费的输出。
作者逐字段走过度量,然后对照软件本身核对了算术:比特币核心报告爱丽丝的交易是 569 权重,与手算吻合。有了每个 vbyte 四个权重、每个区块四百万权重,所选的因子直接转化为合并币时更低的手续费。
“这些因子,以及应用它们的字段,被选来降低花费一个 UTXO 时所用的权重。”
“The factors, and the fields to which they are applied, were chosen to reduce the weight used when spending a UTXO.”
Transactions › Weight and Vbytes查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
为什么延展性会破坏预签名链
交易的 ID 是对其输入脚本计算的,所以重新编码一个被压入的值,或用新的随机数再签一次名,会为同一笔花费产生一个不同的 ID。任何已经签名的子交易都指向旧的 ID,变得无法花费,这就是为什么预签名交易的链条无法以这种方式做到无需信任。
机制 2
隔离见证如何装进一次软分叉
旧节点把由一个 0 到 16 的数字后接 2 到 40 字节数据组成的短脚本,视为任何人都可以用空的输入脚本花费。新节点把这些字节重新解释为版本加见证程序,并把授权数据移到单独的见证结构里,该结构被排除在 txid 之外,所以这次升级只是收紧了现有的规则。
机制 3
权重因子如何给 UTXO 清理定价
每个字段的字节数,在计入四百万权重的区块上限之前,先乘以一个特定于字段的因子,四个权重对应一个 vbyte。这些因子被选来使花费现有输出所需的字段分量很轻,使清理一枚币变得便宜,而创建没人会赎回的微小输出则相对昂贵。
常见误读
粉尘上限是一条共识规则,其作用是阻止用户把自己的钱浪费在毫无意义的小额支付上。
它是中继和挖矿的策略,满是坦率承认任意的数字——许多程序默认拒绝转发低于 546 聪的输出,而这个阈值是可以改变的。它的目的是保护运行全节点的人,因为价值低于花费它所需手续费的输出永远不会被花掉,只会坐在每个全节点都必须追踪的 UTXO 集里。这也是不可花费的 OP_RETURN 数据输出可以豁免的原因。
“因为比特币的去中心化取决于许多人愿意运行全节点,包括比特币核心在内的若干全节点实现,通过影响未确认交易的中继与挖矿的策略,不鼓励创建不经济的输出。”
“Because Bitcoin’s decentralization depends on many people being willing to run full nodes, several full node implementations such as Bitcoin Core discourage the creation of uneconomical outputs using policies that affect the relay and mining of unconfirmed transactions.”
Transactions › Amount查看原文 →
如果隔离见证的输出看起来像任何人都可花费的脚本,那么任何人真的都可以把币拿走,或者旧节点一定在以某种方式检查见证数据。
这两类节点行为不同:升级后的节点执行见证程序,并坚持输入脚本必须为空,而旧节点只是允许输入脚本为空,不验证见证结构里的任何东西。因为新规则只禁止旧规则所允许的,这些币受到网络现在所执行的更严规则的保护。
“从旧节点的角度看,这些输出脚本模板可以用空的输入脚本来花费。”
“From the perspective of old nodes, these output script templates can be spent with an empty input script.”
Transactions › Segregated Witness查看原文 →
第 6 章的核心概念
- 交易输入与输出
- 输入通过出点(txid 加输出索引)指向先前的输出,以声称其中的币。
- 适用处: 节点只在区块链中搜索较早的交易,从不搜索之后的区块。
- 未花费交易输出(UTXO)
- 比特币核心在 UTXO 数据库里追踪可花费的输出,每个区块移除已花费的,加入新的。 每个全节点都必须追踪的可花费币记录,这就是为什么微小的剩余输出很要紧。
- 适用处: 是为效率做的实现选择,不是共识规则。 Utreexo 也许可以让大多数节点只存一个承诺,但仍有一些节点需要完整的 UTXO 数据。
- 序列号字段
- 每个输入四个字节,曾经是替换的版本计数器,现在是 RBF 信号和相对时间锁。
- 适用处: 相对时间锁的含义只适用于版本 2 或更高的交易。
- 交易版本的保留特性
- 版本号让新规则只适用于较新的交易,保护已经签名的旧交易。
- 适用处: 只有协议设计者避开为升级保留的特性时才管用。
- 交易延展性
- 同一笔花费可以被重新编码或重新签名成不同的 txid,破坏预签名交易的链条。
- 适用处: 有时延展性是想要的;sighash 标志有意支持它。
- 隔离见证
- 把花费授权数据排除在 txid 的计算之外,作为一次软分叉,实现在任何人都可花费的输出模板之上。
- 适用处: 新节点要求输入脚本为空;旧节点只是允许它为空。
另外 6 个概念
- 不经济的输出与粉尘
- 价值低于花费它们所需手续费的输出;没人花它们,所以成了全节点的负担,而中继策略不鼓励它们。
- 适用处: OP_RETURN 数据载体输出可以豁免,因为它们不可花费。
- 币基交易
- 区块里由矿工创建的第一笔交易,领取手续费和区块补贴。
- 适用处: 每个区块只有一笔,只有一个输入,且该输入必须指向空 txid、索引为 0xffffffff。
- 区块补贴
- 矿工可以领取的新创造的比特币,与手续费分开;二者合起来构成区块奖励。
- 适用处: 从 50 BTC 开始,每 210000 个区块减半,且只允许到 6720000 号区块为止。
- 成熟规则
- 币基输出在币基交易有 100 个确认之前,不能在区块中被花费。
- 适用处: 适用于币基交易的所有输出;在此之前它们被称为未成熟的。
- 权重
- 衡量交易数据相对于区块上限的现代单位;四个权重等于一个 vbyte。
- 适用处: 区块容纳 400 万权重;每个字段的字节大小乘以一个特定于字段的因子。
- 传统序列化
- 较旧的交易格式,省略了标记、标志和见证结构字段。
- 适用处: 在点对点网络上,凡是见证结构为空的交易都必须使用。
第 6 章划线与批注AI 陪读
“爱丽丝通过说服政府更新记录,写明现在鲍勃拥有这块土地,把那块土地转给了鲍勃”
“Alice transfers that land to Bob by convincing the government to update the record to say that Bob now owns the land”
查看原文 →漂亮的类比,但它夹带了比特币声称要废除的东西——一个登记官。书自己的补救办法是,登记官就是所有人同时;值得注意它在这里没有这么说。
“这不是假设:包括闪电网络在内的几个建立在比特币上的协议,依赖于预签名的交易。”
“This isn’t hypothetical: several protocols built on Bitcoin, including Lightning Network, depend on presigned transactions.”
查看原文 →这就是版本号存在的真正原因:多年前做出的签名,仍然必须得到兑现。比特币只能靠承诺永不打破过去来升级。
“如果没有办法为等价的交易创建新的签名,那么预签名交易中正在花费的钱就永久丢失了。”
“If there’s no way to create a new signature for an equivalent transaction, then the money being spent in the presigned transaction is permanently lost.”
查看原文 →一次共识变更可能悄悄烧掉某人的资金。这使软分叉成为一个道德问题,而不仅仅是工程问题。
另外 15 条批注
“在传统序列化中,标记字节会被解读为输入的数量(零)。一笔交易不可能有零个输入”
“In legacy serialization, the marker byte would have been interpreted as the number of inputs (zero). A transaction can’t have zero inputs”
查看原文 →可爱的把戏——新格式藏在旧格式的一个不可能的值里面。从逻辑漏洞里造出来的向后兼容。
“我们得到一个错误,必须反转它的字节序”
“we get an error and must reverse its byte order”
查看原文 →2009 年的一次意外,此后每个开发者都必须记住。协议把错误固化的速度,比修复它们更快。
“矿工没有直接的动机,偏爱交易的某一个版本胜过任何其他版本。”
“There was no direct incentive for miners to prefer one version of the transaction over any other.”
查看原文 →让一切重新组织起来的诊断:一条没人为遵守它而付酬的规则,就不是规则。RBF 管用,是因为它行贿而不是请求。
“一个因运气不好而有百分之几的时间失败的安全协议,不是一个很有效的协议。”
“A security protocol that fails a few percent of the time due to bad luck isn’t a very effective protocol.”
查看原文 →干巴巴的,却完全正确。安全不是一个你可以四舍五入的概率——对手恰恰就活在那百分之几里。
“每分钟会占用他们个人约 20 KB 的带宽,却占用约 10 GB 的全节点网络带宽”
“would use about 20 KB of their personal bandwidth but about 10 GB of full node network bandwidth every minute”
查看原文 →不对称就是攻击——500000 倍的杠杆。任何一个广播对发送者免费、对其他所有人昂贵的系统,出厂时就预装着这个 bug。
“控制着不经济 UTXO 的人,没有任何动机去花掉它,这可能使它成为全节点运营者永久的负担”
“there’s no incentive for the person controlling an uneconomical UTXO to ever spend it, potentially making it a perpetual burden on operators of full nodes”
查看原文 →缩影中的公地悲剧:你被抛弃的那一分钱的成本,由运行节点的陌生人永远支付。粉尘上限是打扮成技术默认值的社会政策。
“比特币核心的粉尘策略很复杂,含有几个任意的数字”
“Bitcoin Core’s dust policy is complicated and contains several arbitrary numbers”
查看原文 →令人耳目一新的诚实。546 聪是被硬化成常数的民间传说——开发者们抄了一个没人能推导出来的数字。
“分配给它们的任何聪都将永久无法花费——所以允许金额为零,确保聪不会被销毁”
“any satoshis assigned to them become permanently unspendable—so allowing the amount to be zero ensures satoshis aren’t being destroyed”
查看原文 →推理优雅地绕了一圈:之所以允许零,恰恰是因为烧币是可能的。这条规则保护币免受一种设计无法阻止、只能劝阻的毁灭。
“想象一下,数学题的见证会是什么样子。”
“Imagine what a witness would look like for a math problem.”
查看原文 →从法庭到算术的支点,是本章整个概念上的动作——信任被一个你可以插进去并检查的值所取代。节点无法盘问,所以证据必须自己验证自己。
“如果他们知道 Tx0 的签名,其中一方可以在签署退款交易之前广播那笔交易,从而消除退款的保证”
“if they know the signatures for Tx~0~, one of them can broadcast that transaction before signing the refund transaction, eliminating the guarantee of a refund”
查看原文 →这个循环依赖不是数学谜题,而是一场劫持人质的事件。美妙之处在于,修复办法纯粹是关于什么东西被放进哈希里。
“这有点像这样:如果你为同一份合同的两份副本提供手写签名,每个实体签名看起来都会略有不同”
“It’s sort of like how, if you provide a handwritten signature for two copies of the same contract, each of those physical signatures will look slightly different”
查看原文 →这个类比物尽其用——但它也悄悄揭示了缺陷:比特币让一份文件的名字取决于墨水,而不是文本。
“旧节点允许空的输入脚本;新节点要求空的输入脚本”
“old nodes allow an empty input script; new nodes require an empty input script”
查看原文 →整个软分叉就活在“允许”与“要求”之间那一个字的缝隙里。升级即收紧,绝不放松——一条用十一个字陈述的宪法原则。
“它遵循的是抽象不断增加的既有趋势”
“it follows an existing trend of increasing abstraction”
查看原文 →公钥→脚本→见证程序。每一层都用可理解性换来了灵活性,而作者们承认了这种复杂化,而没有把它当作进步推销。
“整个见证结构并不以其所含见证栈总数的任何指示开头”
“the overall witness structure doesn’t start with any indication of the total number of witness stacks it contains”
查看原文 →一种靠让解析器记住前面的某件事来省一个字节的格式。在这里,优雅与脆弱是同一个决定。
“这些因子,以及应用它们的字段,被选来降低花费一个 UTXO 时所用的权重”
“The factors, and the fields to which they are applied, were chosen to reduce the weight used when spending a UTXO”
查看原文 →所以见证折扣不是对采用隔离见证的让步——而是一个经过设计的价格信号,让自己收拾残局变得便宜。手续费策略即垃圾回收。
读后感AI 陪读
比特币的数据格式是约束的记录,不是设计
第6章一开始就拆毁了大多数新手心中的图景:没有币,没有从一个手掌递到另一个手掌的代币,只有一本条目会被改写的账簿。开篇的土地登记簿类比是干净而有用的,但它悄悄引入了比特币本来要废除的那个机构——一个可以被说服的登记官。书的回答是,登记官就是所有人同时,但它在这里没有这么说,所以细心的读者在它说出来之前,应当把这个类比保持在一臂之外。从这里起,本章做了一件我敬佩的事:它取一笔序列化的交易,从左到右逐字节走一遍,拒绝让抽象替代机制。版本、隔离见证的标记和标志、带着出点的输入、输入脚本、序列号、输出、见证、锁定时间——每个字段都带着它的历史到来,而历史才是真正的教训所在。
逐字段的巡礼累计揭示的,是比特币的数据格式是一份约束的记录,而不是一个设计。版本字段之所以存在,是因为预签名的交易——闪电网络的通道、退款路径——是多年前做出的签名,仍然必须得到兑现;协议只能通过承诺永不打破过去而向前推进,而本章坦率得令人钦佩:一次共识变更可能使一笔预签名的花费无法满足,悄悄地烧掉某人的资金。这把软分叉重新框定为一种伦理承诺,而不仅仅是工程策略。隐藏在一个不可能的传统值(零个输入)里的隔离见证标记,是同一承诺变成的一个把戏:一种新格式,穿过旧格式的逻辑漏洞被偷运进来。txid 的字节序反转,是这一承诺更丑陋的一面——2009 年的一次意外,此后每个开发者都必须背负,证明协议把错误固化的速度,比纠正它们更快。
继续阅读
延展性的故事是本章的思想中心。让一切在我这里重新组织起来的诊断,是激励形态的:矿工没有理由偏爱一笔交易的某个变体胜过另一个,而一条没人为遵守它而付酬的规则,就不是规则。这一句话,解释了为什么 RBF 管用(它是行贿而不是请求),为什么粉尘策略是穿着技术常数外衣的社会判断(546 聪是被硬化成一个没人能推导的数字的民间传说),为什么不经济的 UTXO 是公地悲剧——运行节点的陌生人要永远为你被抛弃的那一分钱买单,以及为什么见证折扣最好不要读作对采用隔离见证的贿赂,而是一个让自己收拾残局变得便宜的价格信号——手续费策略即垃圾回收。同样的透镜,把中继带宽的不对称暴露为一种攻击而不是低效:发送者 20 KB 的带宽,对网络 10 GB 的带宽,大约是 500000 倍的杠杆,任何一个广播对发送者免费、对其他所有人昂贵的系统,出厂时就预装着这个 bug。
见证的概念是本章最好的概念支点——从法庭证词,变成你插进一道数学题里的一个值。节点无法盘问,所以证据必须自己验证自己,一旦你看出这一点,整个脚本和见证程序的架构就各就各位了。关于延展性的手写签名类比物尽其用,然后背叛了它所说明的缺陷:比特币曾让一份文件的名字取决于墨水而不是文本。那个破坏了退款交易的循环依赖不是一道谜题,而是一场劫持人质的事件,而补救办法不过是改变放进哈希里的东西,这真的很优雅。软分叉的机制用十一个字陈述,值得背下来——旧节点允许空的输入脚本;新节点要求有一个。升级即收紧,绝不放松;比特币演进的全部宪法逻辑,就在“允许”与“要求”之间的缝隙里。我也欣赏作者们承认了代价:从公钥到脚本到见证程序,是一种抽象不断增加的趋势,用可理解性换取灵活性,而他们称之为复杂化,而不是把它当作进步推销。见证结构省略栈计数——靠让解析器记住前面的某件事来省一个字节——是缩影中的同一笔交易,在那里优雅与脆弱原来是同一个决定。
收尾的这一段继续赢得注意,而不是滑行:币基交易,带着它的空出点和自由格式的币基字段、补贴、悄悄编码了对重组期待的一百个区块成熟规则;用加权和 vbyte 系统取代简单的大小上限,使区块容量可以不经硬分叉就被重新定价;以及为没有见证结构的交易保留的传统序列化,那是本章的论点重述为一种文件格式。那段关于安全的旁白在我心里留下,作为本章最尖锐的思路——一个因运气不好而有百分之几的时间失败的协议,不是一个有效的协议,因为对手不会对结果取平均,他们恰恰就活在那百分之几里。
我要对读者说的是:别把这一章当作字段的参考表来略读。把它读成用字节写成的制度史。每一个怪异之处——反转的哈希、零标记、任意的粉尘阈值、四比一的权重因子、之所以允许存在是因为烧币是可能的、不应被变成强制的零值输出——都是某个人在压力下做出的决定,通常是为了避免打破已经存在的钱。并且通过延展性一节交到你手里的激励问题,来读一切:谁被付酬去遵守这条规则?如果答案是没人,规则就是一个建议,而本章会确切地告诉你,那已经在哪里让人亏了钱。
在 FeedLitra 里读第 6 章,每段旁边都有这些卡片。
开始读书第 7 章:授权与认证
P2SH 地址是如何编码脚本哈希,让客户去支付的?
第 7 章是怎样展开的AI 辅助
开篇:一个区分,然后一件刻意很弱的工具。 本章一开始,把一个单一的直觉——“谁控制这些币”——拆成两个独立的问题:授权(谁可以花费)和认证(节点如何验证某人可以花费)。这个拆分,使本章其余部分变得可读,因为接下来的一切,都是表达一个条件的机制,和检查它的机制。Script 随后作为两者的工具登场,而作者立刻把它的局限放在前面:它是一种栈语言,无状态,非图灵完备。关键在于,这些被呈现为选择,而不是缺陷。论证从谁来承担验证的成本说起:每个全节点都要重新验证每一笔交易,所以一个能循环的脚本,会让一个攻击者给整个网络强加无限的工作量。无状态在达成一致上做着平行的工作——评估之前和之后都没有任何东西持续存在,所需的一切都来自脚本和花费交易,所以如果一个节点接受了一个脚本,所有节点都会接受。验证变得普遍,而不是局部的。框架定好之后,标准的模式登场:P2PKH、裸多重签名(尽职地注明了其哑元素的怪异之处)和 P2SH。
第一个展开:把脚本藏在哈希后面。 P2SH 是本章的经济学推理变得明确的地方。作者用反例来建立论证——穆罕默德的公司和它的裸 2-of-5 条件,那得交给每一位客户,要求特殊的钱包软件,让交易手续费大约膨胀五倍,并永远坐在每个节点的 UTXO 集里。用它的哈希来替换这个条件,一举化解了所有这些:付款人付给的东西短得像单密钥地址,而长长的赎回脚本,由花费者在一次性的输入里发布一次。数据和手续费从发送者转到接收者,从 UTXO 集转到链上。本章小心地给这种便利定价。因为输出只承诺于一个哈希,而哈希对其背后的脚本是否有效、是否可满足毫无说明,格式错误的条件毫无阻碍地通过网络,只在花费时才浮现——那时资金已经永久卡住了。以 3 开头的格式良好的地址和被接受的付款,都不是可恢复性的证据。
向内的转折:条件移进输出本身。 从这里起,本章扩展了一个输出能说什么。OP_RETURN 增加了可证明不可花费的数据输出。然后是时间锁,而在这里作者做出了他最尖锐的动作:先造一个较弱的工具,然后把它打破:爱丽丝预签名的、锁定三个月的交易,只保证鲍勃不能提前赎回,因为爱丽丝可以广播一笔冲突的交易,花费同样的输入,完全没有锁定时间。修复是结构性的——用 OP_CLTV 把延迟写进输出脚本,并立即把资金发到鲍勃的密钥,现在鲍勃还在等他的三个月时,爱丽丝就不能花了。只有当时间锁存在于输出里,而不是预签名的交易里时,它才约束双方。相对时间锁(序列号、OP_CSV)推广了这个想法,而通过 OP_IF 和 VERIFY 操作码的流程控制,让几个条件作为一个赎回脚本里的分支共存,汇集到穆罕默德那个复杂的多路径示例里,作为这一节的回报。
支点:新的输出形式,以及把一切写下来的代价。 隔离见证 v0 用“版本加见证程序”的形式取代了传统模板——P2WPKH 和 P2WSH,外加为向后兼容而嵌套在 P2SH 里的变体。但更重要的支点,是对本章刚刚花了好几页构建的分支脚本的批评。在一个脚本里写明每个条件,既昂贵,又有界,又自我暴露:传统脚本上限 10000 字节,只留出几百个分支的空间,而你写下的每个替代方案,在你花费的那一刻都变成公开的。MAST 一举回答了这三个问题,办法是把完整的替代脚本承诺于一个默克尔根,这样一次花费只揭示所用的分支加上它的路径,容量按对数增长——512 字节里的十六个承诺,覆盖超过 32000 个替代方案。作者克制着不去夸大它:对一个三条件的脚本,默克尔证明的花费是 383 字节,对比 412 字节,再按预期使用率给树排序,又省 32 字节,而且只在常见情形下。大约 7%。Pay-to-contract 和无脚本多重签名随后作为压缩和隐藏的进一步办法,无脚本签名保持恒定大小和私密——代价是公认的:门限签名不记录谁签了名,所以卡罗尔永远无法证明她不是那两个人之一。本章把这笔交易被几乎普遍接受,框定为关于用户偏好的陈述,而不是关于问责得以保留的陈述。
收尾:看起来什么都不是的合作。 Taproot 通过把一个可调整的公钥与一个 MAST 根结合,收拢了这些线索,于是合作的情形是一次便宜、私密的密钥路径花费,而脚本树作为后备在一旁等着,tapscript 则为 Schnorr 改写了 Script。收尾的论证不是取自密码学,而是取自日常生活:大多数合同永远走不到法官面前,因为一旦结果可预测,满意的各方就直接履行,并以协议结束。Taproot 把那种了结变成一次普通的密钥花费——而本章结束在隐私的后果上,那是一种人群中的隐私,而不是隐藏的隐私。在链上,一份有一百万参与者的合同,因彼此满意而收场,与一个人付一张账单无法区分。
关键论点,以及支撑它们的原文
Script 被有意保持得很弱,是故意的,不是出于疏忽。
作者从谁来承担成本出发论证:每笔交易都由每个全节点验证,所以一个能无限循环的脚本,会让一个攻击者给整个网络强加无限的工作量。排除循环,让复杂性和运行时间保持可预测,代价是需要迭代的计算做不了。
“这些限制确保这种语言不能被用来创建无限循环或其他形式的“逻辑炸弹”,否则它们可能被嵌入交易,导致针对比特币网络的拒绝服务攻击。”
“These limitations ensure that the language cannot be used to create an infinite loop or other form of "logic bomb" that could be embedded in a transaction in a way that causes a denial-of-service attack against the Bitcoin network.”
Authorization and Authentication › Turing Incompleteness查看原文 →
没有状态,才使整个网络的验证达成一致:如果一个节点接受了一个脚本,所有节点都会接受。
基于同样的设计逻辑,作者指出脚本运行之前和之后都没有任何东西持续存在——所需的一切都来自脚本和花费交易本身。这使求值的结果在任何机器上都是确定性的,所以验证是普遍的,而不是局部的。
“如果你的系统验证了一个脚本,你就可以确定比特币网络中的其他每个系统也会验证这个脚本,这意味着一笔有效的交易对每个人都有效,而且每个人都知道这一点。”
“If your system verified a script, you can be sure that every other system in the Bitcoin network will also verify the script, meaning that a valid transaction is valid for everyone and everyone knows this.”
Authorization and Authentication › Stateless Verification查看原文 →
P2SH 的存在,是为了让支付到一组复杂的条件,变得像支付到一把密钥那样简单,把复杂性推迟到赎回的时候。
作者的反例是穆罕默德的公司:一个裸的 2-of-5 多重签名条件,必须交给每一位客户,要求客户运行特殊的钱包软件,让交易在手续费上大约大了五倍,并永远坐在每个节点的 UTXO 集里。用脚本哈希来取代它,就把那个长脚本放进花费者的输入里,在那里它只存一次,并在将来由资金的接收者来付费。
“这把手续费和复杂性的负担,从花费者转移到了交易的接收者身上。”
“This shifts the burden in fees and complexity from the spender to the receiver of the transaction.”
Authorization and Authentication › Pay to Script Hash查看原文 →
另外 3 个论点
时间锁只有写进输出脚本里,而不是写进预签名的交易里,才真正约束双方。
作者先立起较弱的工具,然后把它打破:爱丽丝预签名的、锁定三个月的交易,只保证鲍勃不能提前赎回它,因为她可以广播一笔冲突的交易,花费同样的输入,没有锁定时间。用 OP_CLTV 把延迟移进输出脚本,并立即把资金发到鲍勃的密钥,就修好了——爱丽丝再也不能花了,而鲍勃仍要等满三个月。
“唯一的保证是,在 3 个月过去之前,鲍勃无法赎回这笔预签名的交易。”
“The only guarantee is that Bob will not be able to redeem the presigned transaction before 3 months have elapsed.”
Authorization and Authentication › Transaction Lock Time Limitations查看原文 →
把每个花费条件都写在一个分支脚本里,既昂贵,又受大小限制,又公开暴露——而这正是默克尔承诺的脚本树要解决的问题。
作者先给出了限制:传统脚本上限 10000 字节,只留出几百个条件分支的空间,而你写下的每个条件,在你花费的那一刻就变成公开的。相比之下,三条件脚本的默克尔证明花费是 383 字节,而列出所有可能性是 412 字节,再按预期使用率给树排序又省 32 字节——但只在常见情形下,所以对很小的脚本,收益是有限的。
“当你花费受该脚本保护的比特币时,你加到脚本里的每个条件都成了公众知识。”
“Every condition you add to your script becomes public knowledge when you spend bitcoins protected by that script.”
Authorization and Authentication › Merklized Alternative Script Trees (MAST)查看原文 →
Taproot 真正的隐私胜利,是它把你藏进的人群:复杂的合约了结时,看起来与日常支付完全一样。
作者从日常生活出发推理,那里大多数合同永远走不到法官面前,因为满意的各方直接履行并了结;一旦合同的结果变得可预测,参与者可以通过协议终结它。Taproot 把这种经协议的了结变成一次普通的密钥花费,所以在链上,没有什么能把一份有一百万参与者、因彼此满意而收场的合约,与一个人付一张账单区分开来。
“如果一份合约的所有参与者都认识到,它的结果已经变得完全可预测,那么他们实际上就不需要继续使用这份合约了。”
“If all of the participants in a contract recognize that its outcome has become completely predictable, there’s not actually any need for them to continue using the contract.”
Authorization and Authentication › Taproot查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
有界的脚本阻止 DoS
脚本不能循环,所以执行时间和复杂性在节点运行它们之前就被限定了。因为每个全节点都要重新验证每一笔交易,一个无界的脚本会给整个网络强加无限的工作量;这个限制,就是去掉那个攻击面的东西。
机制 2
先哈希,后出脚本
P2SH 输出只存条件的哈希,所以付款人付给的东西短得像单密钥地址,而长长的赎回脚本由花费它的人发布。数据和手续费因此从发送者转到接收者,从每个节点的 UTXO 集转到区块链上的一次性输入。
机制 3
树上的一个分支
把一组完整的替代脚本承诺于一个默克尔根,意味着一次花费只揭示实际所用的分支加上它的路径,所以容量按对数而不是线性增长。十六个承诺(512 字节)覆盖超过 32000 个替代方案,不过只有三个条件时,节省只有区区 7%。
常见误读
如果一个以 3 开头的地址格式良好,而网络接受了我对它的付款,这些币就一定是可恢复的——条件里的错误会在一开始就被拒绝。
输出只承诺于赎回脚本的哈希,而哈希对它所代表的脚本是否有效、是否可满足毫无线索。错误只在有人试图花费时才浮现,那时资金已经永久卡住了;这就是 P2SH 的便利所带来的代价。
“这造成了一种风险,因为你可以把比特币发送到一个之后无法花费的 P2SH 地址。”
“This creates a risk because you can send bitcoin to a P2SH address that cannot be spent later.”
Authorization and Authentication › Redeem Script and Validation查看原文 →
无脚本多重签名只是基于脚本的多重签名更便宜、更好的版本,所以没有理由保留旧的形式。
它确实保持为一个看起来普通的、固定大小的签名,隐私更好,但这是一笔交易:门限签名不记录谁签了名。爱丽丝和鲍勃的二选三花费,与任何其他一对都无法区分,所以卡罗尔没有办法证明她没有参与——作者指出大多数用户接受这一点,那是关于偏好的判断,而不是关于问责得以保留的判断。
“另一个缺点是,门限签名不透露谁签了名。”
“The other downside is that threshold signing doesn’t reveal who signed.”
Authorization and Authentication › Scriptless Multisignatures and Threshold Signatures查看原文 →
第 7 章的核心概念
- 授权与认证
- 授权决定谁被允许花费一个输出;认证是节点区分被允许的花费者与其他所有人的方式。
- 适用处: 两者都只通过交易中的脚本来表达;交易数据之外的任何东西都不算数。
- Script 语言
- 一种简单的、类似 Forth 的栈语言,用来写输出里的条件,和输入里满足这些条件的数据。
- 适用处: 不是通用的:没有循环,也没有条件之外的复杂流程控制。
- 图灵不完备
- 脚本不能循环,所以它们的复杂性和执行时间保持可预测且有界。
- 适用处: 防止逻辑炸弹,但也排除了需要迭代的计算。
- 无状态验证
- 脚本自带运行它所需的一切,所以它在每台机器上的求值方式都相同。
- 适用处: 状态必须只来自脚本和花费交易;两次执行之间不保留任何东西。
- 输出脚本与输入脚本
- 输出脚本设定花费条件;输入脚本提供满足这些条件的数据(通常是签名)。
- 适用处: 自 2010 年起它们分开运行,栈从输入传给输出的执行。
- 支付到公钥哈希
- 一个承诺于公钥哈希的输出,通过揭示该密钥外加一个匹配的签名来花费。
- 适用处: 是传统地址的基础;脚本里哈希以十六进制显示,而不是 base58check。
另外 16 个概念
- 脚本式多重签名
- 一个 t-of-k 条件,列出 k 个公钥,要求至少 t 个签名才能花费。
- 适用处: 裸多重签名在中继上限于 3 个密钥;P2SH 允许 15 个,其他脚本每个操作码 20 个。
- 传统的支付到脚本哈希
- 把一个输出锁到赎回脚本的哈希上,花费者之后连同满足它的数据一起出示该脚本。 支付到一个脚本的哈希,编码为看起来正常的、以 3 开头的地址。
- 适用处: 把手续费和复杂性的负担从花费者转到接收者;2012 年引入。 非递归的:P2SH 不能放在 P2SH 的赎回脚本里。
- 数据记录输出(OP_RETURN)
- 一个存储数据、可证明不可花费的输出脚本,所以它永远不会进入 UTXO 集。
- 适用处: 仍然会占用区块链的磁盘空间;把它引用为输入会使交易无效。
- 绝对时间锁(OP_CLTV)
- 一条针对单个输出的规则,要求花费交易的锁定时间达到一个声明的高度或时间。
- 适用处: 高度和时间两类不能在一个脚本内,或一笔交易的各输入之间混用。
- 相对时间锁(OP_CSV)
- 一条规则,要求自输出被确认以来经过了若干区块或秒数,才能花费。
- 适用处: 两类不能在一个脚本里混用,但各输入之间不会像 OP_CLTV 那样冲突。
- 脚本流程控制
- 条件操作码,给脚本几条解锁路径,由输入脚本中的值来选择。
- 适用处: 嵌套不受限制,但共识限制了脚本的字节大小;条件在 IF 之前。
- 支付到见证公钥哈希(P2WPKH)
- 一个版本 0 的隔离见证输出,加一个 20 字节的公钥哈希;签名住在见证里,而不是输入脚本里。
- 适用处: 必须由接收者用压缩公钥构建;未压缩的密钥在隔离见证中是非标准的。
- 支付到见证脚本哈希(P2WSH)
- 一个版本 0 的隔离见证输出,加一个 32 字节的见证脚本的 SHA256 哈希,通过在见证中揭示该脚本来花费。
- 适用处: 使用单次 SHA256(32 字节),而不是 P2SH 的 20 字节哈希,给出 128 位而不是 80 位的安全性。
- 默克尔化的替代脚本树(MAST)
- 承诺于一棵默克尔树里的一组完整的替代脚本,所以花费只揭示所用的分支。
- 适用处: 不同于默克尔化的抽象语法树,后者必须为程序的每个部分揭示一个摘要,浪费空间。
- 支付到合约(P2C)
- 用购买描述的哈希来调整收款人的公钥,使付款人之后能证明买了什么。
- 适用处: 默认私密;除非有一方揭示底层的密钥和描述,否则使用情况是不可观察的。
- 无脚本多重签名
- 参与者把部分公钥合并成一把看起来普通的密钥,所以多方控制不需要多重签名脚本。
- 适用处: 需要协作的密钥设置和部分签名;不同于基于 OP_CHECKSIG 的脚本式多重签名。
- 无脚本多重签名
- 许多签名者产生一个看起来普通的、大小固定的签名。
- 适用处: 获得隐私和大小上的收益,却无法证明哪些参与者签了名。
- Taproot
- 一把经过调整、承诺于脚本树根的公钥。
- 适用处: 当不想要相互满意条款时,要花约 33 字节的开销。
- 密钥路径与脚本路径花费
- 只靠密钥花费,或通过揭示一个叶子脚本及其默克尔路径来花费。
- 适用处: 脚本路径花费还必须发布内部密钥和分支哈希。
- Tapscript
- 用在 taproot 叶子里的、经过调整的 Script 版本。
- 适用处: 去掉了 OP_CHECKMULTISIG,并按 BIP340 要求 Schnorr 签名。
- 相互满意条款
- 一个让所有各方直接同意并便宜地了结的分支。
- 适用处: 只有当每个相关方都合作时才管用。
第 7 章划线与批注AI 陪读
“你的授权指令和花费者的认证证明,将由成千上万个独立的全节点检查”
“Your authorization instructions and the spender proof of authentication will be checked by thousands of independent full nodes”
查看原文 →整章的利害都在这句话里:花费规则必须对永远不会与你见面的陌生人而言是可读的。Script 的一切怪异之处,都由此而来。
“比特币最初的描述,用公钥来授权。”
“The original description of Bitcoin used a public key for authorization.”
查看原文 →安静的承认,白皮书和发布的代码有所不同。发布的系统,已经比它自己的描述更有雄心。
“这确保这种语言不是图灵完备的,意味着脚本的复杂性有限,执行时间可以预测。”
“This ensures that the language is not _Turing Complete_, meaning that scripts have limited complexity and predictable execution times.”
查看原文 →值得注意这个反转:在这里,无能就是特性。一门围绕敌对的陌生人不得能做什么而设计的语言。
另外 17 条批注
“请注意,得到的 UTXO 可以被任何有算术能力、知道数字 2 满足这个脚本的人花费”
“note that the resulting UTXO can be spent by anyone with the arithmetic skills to know that the number 2 satisfies the script”
查看原文 →面无表情的笑话承载着真正的教训——Script 压根不知道所有权。所有权只是一道碰巧很难的谜题。
“出于安全原因,这在 2010 年被改变了,因为一个称为 1 OP_RETURN bug 的漏洞。”
“For security reasons, this was changed in 2010 because of a vulnerability known as the 1 OP_RETURN bug.”
查看原文 →半句话里就丢了出来:有一段时间,任何人都可以花掉任何人的币。书平静的语气,掩盖了这东西离崩溃有多近。
“只有比特币最初的开发者才能告诉我们,那个哑栈元素是 bug 的结果,还是为将来升级做的计划。”
“Only Bitcoin’s original developer could tell us whether the dummy stack element was the result of a bug or a plan for a future upgrade.”
查看原文 →一位消失的作者使意图永远无法读取,于是意外被奉为圭臬。BIP147 把这种含糊冻结成了法律。
“因为弹出哑元素是共识规则的一部分,它现在必须被永远复制下去。”
“Because popping the dummy element is part of the consensus rules, it must now be replicated forever.”
查看原文 →共识没有撤销。一个每个节点都必须同意的系统,永远无法悄悄修复一个错误——它只能继承它。
“P2SH 把一个长脚本的交易手续费成本,从发送者转移到接收者”
“P2SH shifts the transaction fee cost of a long script from the sender to the recipient”
查看原文 →真正的创新是经济性的,而不是密码学的:哈希搬迁了谁来付钱。复杂性没有消失,它被开了发票给想要它的那一方。
“你可能会不小心以一种之后无法花费的方式收到比特币。”
“You might accidentally receive bitcoin in such a way that it cannot later be spent.”
查看原文 →把复杂性藏在哈希后面的反面——网络无法检查它看不见的东西,所以错误要到为时已晚才浮现。
“因此这些永远无法被花费的交易永远不会从 UTXO 集中移除,导致 UTXO 数据库的大小永远增长,或者说“膨胀”。”
“These transactions that can never be spent are therefore never removed from the UTXO set and cause the size of the UTXO database to forever increase, or "bloat.”
查看原文 →真正的反对不是道德上的,而是外部性:存储成本被永远倾倒在每个节点运营者头上。“滥用”的框架是它的下游。
“达成了一个妥协,允许以 OP_RETURN 开头的输出脚本”
“A compromise was reached that allows an output script starting with OP_RETURN”
查看原文 →注意被动语态——“达成了一个妥协”,是谁达成的?比特币的治理就躲在这样的语法里。
“鲍勃无法保证爱丽丝不会那样做。”
“Bob has no guarantee that Alice won’t do that.”
查看原文 →这一节里最尖锐的一行。一笔签名的、带时间锁的交易,感觉像是一个承诺,却只是一个许可——而给予者保留了撤销的权力。
“把时间锁的限制放在 UTXO 本身,作为脚本的一部分,而不是放在交易上”
“place the timelock restriction on the UTXO itself as part of the script, rather than on the transaction”
查看原文 →整个设计转向,一个从句说完:把约束从消息移到钱上。把规则附着在资产上,就没有人需要被信任了。
“之前那些空操作(NOP)操作码的行为必须被保留”
“the behavior of those previous no-operation (NOP) opcodes must be preserved”
查看原文 →所以那个别扭的、悬着的栈项不是设计选择,而是向后兼容的化石。软分叉用丑陋来缴租。
“条件不是脚本的一部分。相反,条件将在花费时提供”
“The condition is not part of the script. Instead, the condition will be offered at spending time”
查看原文 →可爱的反转——锁发布时不指明是哪把密钥;花费者通过选择分支来宣布自己的身份。
“他们希望律师在获得资本账户的交易记录后,能够直接管理该账户”
“they want the lawyer to be able to manage the account directly after he gains access to the capital account’s transaction records”
查看原文 →穆罕默德的脚本其实是一份遗嘱、一份授权委托书和一份公司章程,压缩成十三行。法律时间被区块时间取代。
“无论是花费者还是其他任何人,都不应该把 P2PKH 脚本、比特币地址或未压缩公钥,转换成 P2WPKH 见证脚本。”
“Neither the spender nor anyone else should ever transform a P2PKH script, Bitcoin address, or uncompressed public key to a P2WPKH witness script.”
查看原文 →关于热心如何成为危险的警告:花费者代表接收者“升级”,可能会把资金烧掉。只有接收者知道他们能花什么。
“P2WSH 的 128 位安全性,对比 P2SH 的 80 位安全性”
“128 bits of security in P2WSH versus 80 bits of security in P2SH”
查看原文 →悄悄承认较旧的标准建得不够。隔离见证在一次空间优化的同时,夹带了一个安全修复。
“这是唯一让全节点能够区分两种见证程序的差异。”
“This is the one difference that allows a full node to differentiate between the two types of witness programs.”
查看原文 →一整个类型系统建立在 20 对 32 字节上。优雅,但这也意味着地址空间永久地没有多余的长度了——每个未来的版本都必须重新谈判。
“尽管爱丽丝的钱包不支持隔离见证,她创建的付款仍可由鲍勃用隔离见证交易来花费。”
“Even though Alice’s wallet has no support for segwit, the payment it creates can be spent by Bob with a segwit transaction.”
查看原文 →嵌套的真正把戏:升级的负担完全转移到受益者身上。鲍勃付出复杂性的成本,去收取手续费折扣;爱丽丝从不知情。
读后感AI 陪读
这一章看起来像是对 Script 操作码的技术巡礼,但从头读到尾,它其实是一篇关于一个问题的文章:你如何向成千上万个永远不会与你见面、无法向你提问、而且必须全都得出相同裁决的陌生人,表达一个关于钱的条件?开篇在授权和认证之间的划分,设定了这个框架,此后每一处怪异之处都源于它。Script 有意的弱点——无状态、没有循环、非图灵完备——是第一条线索,表明这不是一种编程语言,而是一种可读性格式:无能就是特性,因为对敌对的陌生人唯一安全的语言,是你能预测其执行时间的语言。而那个面无表情的笑话——任何人只要知道 2 满足脚本,就能花掉一个输出——承载着本章最深的一点:Script 压根没有所有权的概念。所有权是一道碰巧很难的谜题,而密钥只是“难”的一种方式。
从这里起,本章几乎不顾它平静的语气,成了一部无法撤销的后果的历史。关于白皮书描述的是公钥授权、而发布的代码用的却是地址哈希的那个安静的注释,是承认系统从来就与它自己的描述不完全相同。1 OP_RETURN 的 bug 在半句话里就丢了出来,读者应当就此停下:有一段时间,网络的花费规则对每个人都是坏的。裸多重签名的哑栈元素是最纯粹的标本——一个错误,它的作者在任何人能问它是 bug 还是计划之前就消失了,所以这种含糊本身被 BIP147 奉为圭臬,现在必须永远复现。共识没有撤销按钮。一个每个节点都必须同意的系统,永远无法悄悄修复任何东西;它只能继承,并以丑陋来缴租,而这恰恰就是 OP_CLTV 和 OP_CSV 背后被保留的 NOP 语义。
继续阅读
本章的中段,我认为是真正的思想内容所在,而且是经济学的而非密码学的。P2SH 的创新不是对脚本做哈希——而是搬迁了发票。复杂性不会消失在哈希后面;它被计到想要它的那一方头上,而本章诚实地承认,这是双刃剑:网络无法验证它看不见的东西,所以一个格式错误的 P2SH 承诺,会产生看起来已经收到、实际上已经没了的资金。同样的外部性逻辑驱动着 OP_RETURN 的讨论,那里对数据存储的反对不是道德上的,而是账目上的——永远膨胀 UTXO 集的不可花费输出,给每个并未同意的节点运营者强加了成本。注意那里的被动语态:“达成了一个妥协。”比特币的治理总是躲在这样的语法里,值得留意的是,本章多少最重要的决定,是在句子里没有主语的情况下到来的。
时间锁一节包含本章最尖锐的一行:鲍勃无法保证爱丽丝不会那样做。一笔签名的、带时间锁的交易,感觉像是一个承诺;它不过是一个许可,而给予者保留了先花掉它来撤销的权力。修复办法是本章核心的设计动作,用一个从句就说完了——把限制放在 UTXO 上,而不是交易上。把约束从消息移到钱上,就没有人需要被信任了。流程控制然后完成了这个反转:赎回脚本发布时不声明将走哪条路径,花费者通过选择一个分支宣布自己是谁。穆罕默德那个十三行的例子,是一份遗嘱、一份授权委托书和一份公司章程压缩成栈操作,法律时间被区块高度取代——雄心勃勃,也是一个安静的警告:我们在要求一门没有错误消息的语言,承载多大的后果。
隔离见证和 taproot 的内容读起来像是同样的主题带着更好的工具回来了。把隔离见证嵌套进 P2SH,是 P2SH 手续费论证推广成了升级策略:负担完全落在受益者身上,所以鲍勃付出复杂性的成本,去收取他自己的折扣,而爱丽丝的传统钱包从不知道发生过什么。有两个细节值得比书所给予的更多的分量。第一,永远不要把 P2PKH 脚本或地址转换成见证程序的警告,是一个关于热心如何成为危险的教训——只有接收者知道他们实际能花什么,而替他们“升级”的花费者,会把钱烧掉。第二,P2WSH 的 128 位对 P2SH 的 80 位,是在空间优化的掩护下夹带进来的安全修复,而整个见证类型系统建立在 20 对 32 字节的区别上,这很优雅,却让地址空间没有多余的长度;每个未来的版本都不得不重新谈判。MAST、pay-to-contract、无脚本多重签名,最后是 taproot,都用新的语域回答了本章开篇的问题:干脆不再发布条件,发布一个承诺,只揭示你所用的那个分支。Taproot 那把在 MAST 根上调整过的密钥是终点——便宜而无法区分的密钥路径花费,以脚本路径作为后备——而 tapscript 是为适应 Schnorr 而再一次改写的 Script。
我要对读者说的是:别把这一章当作一个为查操作码表而略读的参考章节。把它读成一个约束的传记。每一种模式——P2PKH、多重签名、P2SH、时间锁、隔离见证、taproot——都是试图以更少的暴露说更多的话,弧线从向全世界发布你的条件,到对它们做哈希,再到不透露它们而证明它们。但也要清醒地看待隐私的收益:无脚本多重签名保持恒定大小和私密,恰恰因为它们隐藏了哪些参与者签了名,而这种不透明对于需要审计轨迹、而不仅仅是一次有效花费的人来说,是一项成本。并且把这些意外带在身边。那个本可能把任何人的币抽干的 bug,那个没人能解释的哑元素,那些因善意的地址转换而损失的资金——这些不是一个本来干净的设计上的瑕疵。它们是设计真正的质地,是一个必须由所有人验证、却无人能纠正的系统,看起来的样子。
在 FeedLitra 里读第 7 章,每段旁边都有这些卡片。
开始读书第 8 章:数字签名
三种 SIGHASH 标志在它们省略的字段上究竟有什么不同?
第 8 章是怎样展开的AI 辅助
开篇:三项工作的框架。 本章一开始指出,比特币带有两种签名算法而不是一种——Schnorr 和 ECDSA——这悄悄埋下了一个本章最终将回答的问题。但在碰任何一种之前,作者先确立了一个框架:数字签名必须同时做三件事。它必须证明签名者控制着密钥(授权),使这一证明在事后不可抵赖(不可否认性),并绑定交易的内容,使任何未经认证的第三方都无法改动被授权的东西(完整性)。第三项工作,使开篇不止是一个定义,因为它直通签名/验证的划分,然后是 SIGHASH 标志——签名者选择哪些交易数据被承诺的机制。这里优雅的细节是,标志字节本身被折进了被哈希的消息:交易的一份副本被修剪到标志所覆盖的字段,标志被附上,然后整个东西被哈希。任何后来把标志换成更宽松设置的人,都会破坏验证,所以中继者和矿工无法悄悄放宽或收窄授权的范围。
展开:分阶段建立的 Schnorr。 框架定好之后,作者没有简单地陈述 BIP340 方案;他构造它,从一个交互式身份协议出发,一步一步地加固它。关键的一步是顺序:签名者必须在挑战值被确定之前,发布对一个新的秘密 nonce 的承诺。把顺序反过来,一个已经知道挑战的作弊者,可以随机选一个响应,再反推 nonce 点,使验证等式平衡——一个不知道私钥的通过验证的签名。出于同样“承诺必须覆盖什么”的逻辑,本章把哈希扩展到包含公钥,而不仅仅是 nonce 和消息。省略密钥,攻击者就可以向现有签名加上一个值——甚至不必是秘密的——得到一个对相关的、派生的密钥有效的签名,而所有者从未授权它。既然 BIP32 的非硬化推导恰恰制造这样的相关密钥,hash(kG || xG || m) 就是堵住那个洞的塞子。这番构建然后落在实际的回报上:64 字节(带标志则 65 字节),整个构造所瞄准的紧凑性。
向外的转折:聚合,及其代价。 在确保了单签名者的情形之后,本章展开到 Schnorr 的线性性所使之成为可能的东西——MuSig 家族里的无脚本多重签名,和门限签名。在这里,作者的方法从构造转向拆毁:他走过一个朴素的聚合协议,其中参与者只是把公钥加起来,然后打破它。最后一个揭示的人,可以把他的密钥选成想要的聚合密钥减去其他所有人的;他们的贡献相互抵消,合并后的密钥其实只属于他一个人,他无需帮助就能签名。修复办法——在任何密钥被揭示之前,先承诺密钥的摘要——去掉了后动者的优势,但作者指出,它既容易被错误地实现,又在额外的通信轮次上代价高昂。门限签名得到同样的处理,取舍更尖锐:在链上,这次花费看起来像一个普通的签名,所以没人能说出组里哪些成员参与了。那是隐私,但也是失去的问责,作者的建议直截了当——如果你需要知道谁签了名,就改用脚本。他随后展示了颠覆:一位处于其他人之间的参与者,依次告诉每个人别人不可用,重构出两者的部分密钥,然后拿着整个秘密离开。防御是结构性的,而不是密码学的——让每条消息对所有参与者都可见。
反转:ECDSA 作为历史的意外。 只有在 Schnorr 被建立起来、它的聚合性质被探索之后,作者才把比较反过来,问为什么 ECDSA 会在比特币里。答案是历史性的,而不是技术性的。比特币设计的时候,Schnorr 受专利保护,也不在开放标准里,而 ECDSA 到 2007 年已经躺在可用的库里——可得性决定了它。Schnorr 直到 2021 年才随着 taproot 到来,而 ECDSA 仅仅作为向后兼容而留存,仍然覆盖每一次非 taproot 的花费,尽管它成本更高,缺乏 Schnorr 所享有的那种安全证明,也抗拒聚合。这个位置很要紧:如果比较放在前面,ECDSA 读起来就像是深思熟虑的选择。放在最后,读起来就像是本章已经展示过如何摆脱的一个约束。
收尾:nonce 与哈希修复。 本章以两件来之不易的工程纪律结束。第一,每个签名都需要它自己的 nonce,它必须来自一种规定的确定性方案,而不是临时生成。作者把这立足于历史而不是理论——真实的比特币实现曾经重复使用 nonce,用户因此丢了币,罪魁通常是初始化不当的随机数生成器。因此有了按 BIP340 或 RFC6979 推导 nonce 的指令;确定性去除了对一个你在运行时无法审计的熵源的依赖,这就是为什么这些方案是一项要求,而不是一种便利。第二,隔离见证的 BIP143 承诺哈希,它重新组织了被哈希的内容,使签名成本相对于输入数量,从二次降为 O(n)。两个收尾项目都绕回开篇的框架:它们讲的是,让完整性承诺既产生起来安全,又计算起来便宜——本章的三个目的真正成立的实际条件。
关键论点,以及支撑它们的原文
数字签名必须同时做三项工作:证明签名者控制着密钥,使这一授权不可抵赖,并锁定交易的内容。
作者通过列举三个目的——授权、不可否认性和完整性——把它立为本章的框架,并把最后一个与这样的要求联系起来:任何未经认证的第三方都不能改动一笔被授权的交易。
“首先,签名证明了私钥的控制者——这隐含着他就是资金的所有者——已经授权花费这些资金。”
“First, the signature proves that the controller of a private key, who is by implication the owner of the funds, has authorized the spending of those funds.”
Digital Signatures查看原文 →
基于 nonce 顺序为何重要,BIP340 签名不仅承诺 nonce 和消息,还承诺公钥。
如果承诺里没有密钥,有人就可以向现有签名加上一个不必是秘密的值,得到一个对相关的、派生的密钥验证通过的签名——表面上有效,却从未得到该密钥所有者的授权。既然 BIP32 的非硬化推导恰恰产生这样的相关密钥,把公钥包含进 hash(kG || xG || m),就堵上了这个洞。
“这就构成了完整的承诺 hash(kG || xG || m)。”
“That makes the full commitment hash(kG || xG || m).”
Digital Signatures › Schnorr Signatures查看原文 →
让几个签名者直接把密钥加起来是不安全的;聚合需要一个事先的承诺轮次。
作者走过一个朴素的协议,然后打破它:鲍勃把他的密钥选成想要的聚合密钥减去爱丽丝的密钥,此后他完全无需她的帮助,就能产生一个有效的签名。修复办法——先承诺密钥摘要——被指出既容易被错误地实现,又要多花一轮通信。
“前面的协议有几个安全问题。”
“The preceding protocol has several security problems.”
Digital Signatures › Schnorr-based Scriptless Multisignatures查看原文 →
另外 3 个论点
门限签名用问责换来隐私,而且签名过程本身可能被一个位置得当的中间人所颠覆。
在链上,这次花费看起来像一个普通的签名,所以没人能说出组里哪些成员参与了;如果知道这一点很要紧,作者说应当改用脚本。他随后展示了攻击:一位处于其他人之间的参与者,依次告诉每个人别人不可用,重构出两者的部分密钥,最终拿着整个秘密——如果每条消息对所有参与者都可见,这个把戏就失败了。
“如果知道组里哪些成员签了名很重要,你就需要使用脚本。”
“If it’s important to know which members of the group signed, you will need to use a script.”
Digital Signatures › Schnorr-based Scriptless Threshold Signatures查看原文 →
把比较反过来,ECDSA 出现在比特币里是出于历史而不是技术的原因。
比特币设计的时候,Schnorr 受专利保护,也不在开放标准里,而 ECDSA 到 2007 年已经躺在可用的库里,所以比特币带着它发布。Schnorr 直到 2021 年才随着 taproot 到来,而 ECDSA 仍然覆盖每一次非 taproot 的花费。
“对比特币和许多其他应用的未来发展来说,不幸的是,克劳斯·施诺尔为他发现的算法申请了专利,并在近二十年里阻止了它在开放标准和开源软件中的使用。”
“Unfortunately for the future development of Bitcoin and many other applications, Claus Schnorr patented the algorithm he discovered and prevented its use in open standards and open source software for almost two decades.”
Digital Signatures › ECDSA Signatures查看原文 →
每个签名都需要它自己的 nonce,由一种规定的确定性方案生成,而不是临时生成。
作者指出了真实的比特币实现里,nonce 被重复使用、用户丢了币的情形,并指认初始化不当的随机数生成器为通常的罪魁——这就是为什么他指示实现者按 BIP340 或 RFC6979 推导 nonce。
“如果你在实现比特币的交易签名算法,你必须使用 BIP340、RFC6979 或类似的算法,来确保你为每笔交易生成不同的 k。”
“If you are implementing an algorithm to sign transactions in Bitcoin, you must use BIP340, RFC6979, or a similar algorithm to ensure you generate a different k for each transaction.”
Digital Signatures › The Importance of Randomness in Signatures查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
对 SIGHASH 字节本身签名
交易的一份副本被修剪到所选标志所覆盖的字段,然后附上标志字节,再把整个东西哈希成要签名的消息。因为标志在哈希之内,任何后来把它换成更宽松设置的人,都会破坏验证,所以矿工或中继者无法悄悄放宽或收窄被授权的内容。
机制 2
先 nonce,后挑战
签名者必须在挑战值被确定之前,发布对一个新的秘密 nonce 的承诺。如果顺序反过来,一个已经知道挑战的作弊者,可以随机选择响应,然后反推 nonce 点,使验证等式平衡,产生一个不知道私钥的通过验证的签名。
机制 3
密钥抵消是如何起作用的
当参与者只是把他们的公钥加起来时,最后一个揭示密钥的人,可以把他的密钥选成目标聚合密钥减去其他所有人的密钥。其他人的贡献抵消掉了,所以合并后的密钥其实只是他自己的,他可以独自签名。强迫每个人在任何密钥被揭示之前先承诺其密钥的摘要,就去掉了后动者的优势。
常见误读
比特币使用 ECDSA,是因为它被判定为更强或更合适的签名方案,而 Schnorr 是较新的发明,直到最近才变得足够好。
Schnorr 原则上是有的,却被专利锁住,也不在开放标准里,而 ECDSA 已经存在于发布的库中,所以可得性决定了一切。Schnorr 在 2021 年的到来是随着 taproot,而 ECDSA 的继续存在,纯粹是为了所有非 taproot 花费的向后兼容。
“对比特币和许多其他应用的未来发展来说,不幸的是,克劳斯·施诺尔为他发现的算法申请了专利,并在近二十年里阻止了它在开放标准和开源软件中的使用。”
“Unfortunately for the future development of Bitcoin and many other applications, Claus Schnorr patented the algorithm he discovered and prevented its use in open standards and open source software for almost two decades.”
Digital Signatures › ECDSA Signatures查看原文 →
只要我的 nonce 取自随机数生成器,我的签名代码就没问题——确定性 nonce 方案只是可选的便利。
作者的指示是通过 BIP340 或 RFC6979 确定性地推导 nonce,恰恰因为致命的重用情形,通常的原因是初始化不当的随机数生成器;这已经让真实的比特币用户丢了资金。确定性去除了对一个你在运行时无法审计的来源的依赖。
“如果你在实现比特币的交易签名算法,你必须使用 BIP340、RFC6979 或类似的算法,来确保你为每笔交易生成不同的 k。”
“If you are implementing an algorithm to sign transactions in Bitcoin, you must use BIP340, RFC6979, or a similar algorithm to ensure you generate a different k for each transaction.”
Digital Signatures › The Importance of Randomness in Signatures查看原文 →
第 8 章的核心概念
- 数字签名
- 一对算法:一个用私钥对交易哈希创建签名,另一个让任何人用公钥验证它。
- 适用处: 只要 OP_CHECKSIG 系列操作码或密钥路径花费执行,就需要。
- SIGHASH 标志
- 附在签名后面的一个字节,说明签名承诺交易的哪些部分。
- 适用处: 可以因输入而异,甚至同一输入内的每个签名也可以不同;标志有 ALL、NONE、SINGLE 加 ANYONECANPAY。
- Schnorr 的线性性
- 可加性加同质性,所以函数内部和外部的运算给出相同的结果,让各方无需分享秘密就能合作。
- 适用处: 使无脚本的多重签名/门限签名和批量验证成为可能。
- Fiat-Shamir 变换
- 用爱丽丝公开 nonce 的哈希,取代鲍勃的随机挑战,把交互式证明变成独立的签名。
- 适用处: 取决于哈希输出不可预测,却又是确定性的。
- 私有 nonce
- 一个新的大随机标量 k,其公开形式 kG 在签名等式中隐藏了私钥。
- 适用处: 如果 nonce 在任何方面可预测,安全就会崩塌。
- 无脚本多重签名
- 几个签名者合并密钥和 nonce,使链上只看到一个普通的签名。
- 适用处: 只对 k-of-k 签名有效;每个参与者都必须贡献。
另外 4 个概念
- 密钥抵消攻击
- 一个后到的参与者选择一把能抵消其他人的密钥,于是只有他自己控制聚合密钥。
- 适用处: 在共享密钥之前先承诺密钥摘要,即可防止。
- 无脚本门限签名
- 一个门限子集通过可验证的秘密共享,重建缺席成员的部分密钥来签名。
- 适用处: 无法证明究竟是谁签了名;如果这很要紧,就用脚本。
- nonce 重用
- 用同一个 k 对两条消息签名,任何人都可以算出私钥。
- 适用处: 用 BIP340 或 RFC6979 的确定性 k 即可避免。
- 隔离见证
- 隔离见证 v0 还改变了签名承诺哈希的计算方式。
- 适用处: BIP143 适用于隔离见证版本 0 的见证程序。
第 8 章划线与批注AI 陪读
“不幸的是,这个协议可以被筹款人加一个自己的输入而绕过”
“Unfortunately, this protocol can be circumvented by the fundraiser adding an input of their own”
查看原文 →难得的坦率时刻——书构造了优雅的众筹把戏,然后在同一段里把它推倒。密码学是无懈可击的;激励不是。
“通过包含 SIGHASH 标志本身,签名也承诺了 SIGHASH 类型,所以它无法被更改(比如被矿工)”
“By including the SIGHASH flag itself, the signature commits the SIGHASH type as well, so it can’t be changed (e.g., by a miner)”
查看原文 →自我指涉的补丁:关于覆盖什么的规则,本身必须被覆盖。否则矿工就直接改写你同意的范围。
“这允许冒充者在等式两边都改变参数”
“This allows the impersonator to change parameters on both sides of the equation”
查看原文 →本章在这里物有所值。安全不在代数里,而在顺序里——先承诺,后被挑战。把协议的两行颠倒,它就崩塌了。
另外 11 条批注
“因为爱丽丝无法预测哈希函数的输出(挑战),而且对同样的输入它总是相同的”
“Because Alice can’t predict the output of the hash function (the challenge), and because it’s always the same for the same input”
查看原文 →Fiat-Shamir 是整章的障眼法:爱丽丝对自己扮演鲍勃的角色,而哈希函数被信任为一个公正的裁判。优雅——而且完全取决于那份信任。
“也可以把那个非秘密的值加到一把密钥的有效签名上,产生一个相关密钥的签名”
“it’s also possible to add that nonsecret value to a valid signature for one key to produce a signature for a related key”
查看原文 →一个无人授权的有效签名。本章对“数学上有效”和“实际上同意”是不同谓词的最好说明。
“我们即将描述的这个简单协议是不安全的,原因我们稍后就会解释”
“The simple protocol we are about to describe is not secure for the reasons we will explain shortly”
查看原文 →靠有意领着你走进陷阱来教学。注意它与单签名的情形完全镜像——这恰恰就是诱惑:线性性让有缺陷的版本看起来显然是对的。
“鲍勃用 zG – yG 生成他的公钥”
“Bob generates his public key using zG – yG”
查看原文 →优雅的恶意:鲍勃没有破坏数学,他是让数学把爱丽丝抵消掉。整个协议的对称性,就是它的弱点。
“很容易没能正确实现这个方案”
“it’s easy to fail to implement this scheme correctly”
查看原文 →埋在段落中间的诚实承认——修复在纸面上稳健,在代码里脆弱。那道缝隙就是真钱丢失的地方。
“没有任何一个多重签名协议可以在所有情形下推荐”
“there’s no single multisignature protocol to recommend in all cases”
查看原文 →教科书拒绝开处方,很少见。然后它还是立刻开了 MuSig2 的处方——诚实之后是务实。
“门限数量的参与者有能力重构部分私钥”
“a threshold number of participants have the ability to reconstruct the partial private keys”
查看原文 →所以这里的“门限”不是一个较弱的签名——而是偷你伙伴密钥的许可。把整个方案重新框定为相互劫持人质。
“现在鲍勃有了他自己的部分私钥,加上爱丽丝和卡罗尔的密钥”
“Now Bob has his own partial private key plus the keys of Alice and Carol”
查看原文 →这一段里最好的一处:鲍勃的攻击办法,是告诉两位女士,对方缺席。纯粹是穿着密码学外衣的社会工程。
“克劳斯·施诺尔为他发现的算法申请了专利,并阻止了它的使用”
“Claus Schnorr patented the algorithm he discovered and prevented its use”
查看原文 →因为一项专利,两个十年的较差的密码学。比特币最初的签名方案是一件法律产物,而不是技术选择。
“经过 30 年,ECDSA 似乎不太可能被证明”
“it seems unlikely after 30 years that ECDSA will be proven”
查看原文 →这个免责声明是加锐而不是缓和——他们是在说“我们不是专家,同时:放弃吧”。
“k 的值并不重要,只要它是随机的。”
“The value of k is not important, as long as it is random.”
查看原文 →一句话既真实,又灾难性地误导。下一段把力气都花在撤销它上面——最佳实践是让 k 根本不随机。
读后感AI 陪读
第8章是全书教学上最诚实的一章,也是诚实最容易被错过的一章,因为它总是把警告埋在它刚刚推销完的优雅之中。它开篇足够传统——两种签名算法(Schnorr 和 ECDSA)、三个目的(授权、不可否认性、完整性)、干净的签名/验证划分——然后很快揭示,有趣的问题不是你如何签名,而是你签的是什么。SIGHASH 一节就是这个支点发生的地方:签名不是对一笔交易的祝福,而是对其中一个选定子集的祝福,而子集的选择就是整个安全面。众筹的例子是本章最好、最坦率的时刻——它构造了一个可爱的 SIGHASH_SINGLE|ANYONECANPAY 把戏:陌生人可以各自认捐一个输入,凑向一个固定的输出,然后在同一口气里把它拆毁,指出筹款人可以加一个自己的输入。数学并没有坏。坏的是激励。而附近那个自我指涉的补丁——SIGHASH 字节本身必须在它所管辖的哈希之内,否则矿工就直接改写你同意的范围——是本章其余部分一再证明的小小结构性教训:关于覆盖范围的规则,本身必须被覆盖。
Schnorr 的构建是最强的一段文字。从交互式身份协议出发,经过有意推进的有缺陷的中间版本,本章表明安全存在于顺序之中,而不是代数:先承诺 nonce,后被挑战。把这两行颠倒,冒充者就可以在等式两边都移动参数,一个在纸面上看起来一样的方案就崩塌了。然后 Fiat-Shamir 作为本章核心的障眼法到来——用承诺和消息的哈希取代鲍勃,爱丽丝就可以对自己运行挑战,非交互式地、永远地运行。它真的很美,而且完全取决于哈希是一个没人能预料或操纵的公正裁判。本章轻描淡写地提了一句,就继续往下了。我本想让它多停留一会儿:现代密码学中的每一个非交互式证明,都依赖于那一次委托的信任。
继续阅读
从这里起,本章转向对抗,细心的读者应该在这里放慢。密钥抵消是整篇文字里最尖锐的想法:鲍勃并没有击败朴素的密钥聚合,他是让数学来击败爱丽丝,办法是发布 zG − yG,于是公钥之和成了一把只有他能控制的密钥。让方案优雅的那种对称性,恰恰是让它可被利用的东西。同样的形状在密钥调整中重现,一个非秘密的加数,把一个有效的签名变成了相关密钥的有效签名——全书中最干净的演示,表明“数学上有效”和“实际上被授权”是不同的谓词,而验证只检查第一个。门限签名的讨论落在同一点上:门限数量的参与者能够重构其他人的部分私钥,这把 t-of-n 重新框定为不是一个较弱的签名,而是一种相互人质的安排——而鲍勃的攻击,告诉爱丽丝卡罗尔缺席,又告诉卡罗尔爱丽丝缺席,是穿着密码学外衣的社会工程。然后是我最敬佩的承认:没有任何一个多重签名协议可以在所有情形下推荐。教科书拒绝开处方,很少见。然后它还是开了 MuSig2 的处方,这是诚实之后的务实,也好——但读者应当注意到前半句,而不只是后半句。
ECDSA 一节是本章安静的控诉。ECDSA 存在于比特币里,不是因为它更好,而是因为 Schnorr 被专利封锁:签名更大,验证更慢,三十年后仍没有安全证明,还有一个非线性的结构,使聚合实际上不可能。两个十年的较差的密码学,作为一件法律产物。书的限定——“经过 30 年,ECDSA 似乎不太可能被证明”——是加锐而不是缓和了这一点。而 nonce 的讨论包含本章最危险的一句话:“k 的值并不重要,只要它是随机的。”孤立来看是真的,作为指导却是灾难性的,而随后的几段把力气都花在撤销它上面。在两个签名中重复使用 k,私钥就会通过简单的代数掉出来;这不是理论上的,它已经抽干了真实的钱包,破解了真实的游戏机。这就是为什么 BIP340 和 RFC6979 让 k 具有确定性——由密钥和消息推导——使正确性不再依赖于一个你无法审计的熵源。本章反复出现的叠句——这些方案很容易被不正确地实现——是要带走的那句话:纸面上稳健,代码里脆弱,而这道缝隙就是钱真正消失的地方。隔离见证的 BIP143 承诺哈希,在另一个语域上结束了本章——一个把二次哈希变成 O(n) 并去除了一个拒绝服务向量的工程修复——提醒我们签名设计同时也是一个性能和资源耗尽的问题,而不仅仅是一个对抗性数学的问题。
我想对读者说的是:别把这一章读成算法的菜单。把它读成一个持续的论证:密码学的失败几乎从不以数学被攻破的方式到来。它以一个被重复使用的 nonce、一个被重新排序的协议步骤、一次没有持有证明就求和的密钥、一个没有被承诺的 SIGHASH 标志、一个声称另一个伙伴离线的伙伴、一项把技术水平冻结了二十年的专利的方式到来。本章的代数始终站得住;一切破裂,都发生在它周围。对这里的每一个优雅构造,在你知道它对顺序、对随机性、对还有谁持有密钥、对签名实际覆盖什么做了什么假设之前,都把它当作暂定的。
在 FeedLitra 里读第 8 章,每段旁边都有这些卡片。
开始读书第 9 章:交易手续费
交易钉住究竟是如何让对手阻止一次替换的?
第 9 章是怎样展开的AI 辅助
开篇:拍卖的框架。 本章不是从一条规则开始的,而是从稀缺的图景开始。区块以有限的速率到来,每个区块的空间有限,所以一个想最大化收入的矿工,只能纳入装得下的、付费最高的那一组。从这一个观察,作者推出了本章的组织性主张:手续费不是标出来的价格,而是一次竞争性的出价,而且因为要紧的是交易占用多少空间,矿工按每单位大小的手续费,而不是总手续费,来给候选交易排名。两个推论随之而来。第一,惯例上是花费者在付费——每次花费都必须被认证,所以没有花费者同意就不能附加手续费,而花费者通常是最急于快速确认的一方;承诺一笔手续费并不占用额外空间,这使由花费者支付的单笔交易成为最便宜的途径。作者承认存在例外(接受未确认付款的商家、预签名的协议),而没有夸大这条规则。
展开:估算,然后是追加。 因为这个水平是在公开拍卖中设定的,没有人能预先知道什么费率会获胜,所以本章转向估算,把它当作一场从近期历史中推断的练习:工具观察最近广播的交易实际多快被确认,并据此外推。演示的例子——向节点询问一天的目标 144 个区块,得到一个具体的 0.00006570——恰恰是为了表明这个数字的脆弱,因为需求在广播之后可能转移,使估算出错。这种过时,引出了下一节。手续费追加有两种风味,取舍分明:替换(RBF)节省空间,但通常需要原签名者,而子交易(CPFP)可以由任何持有输出的人构造,但会占用额外的区块空间。CPFP 之所以能起作用,只是因为矿工按父子捆绑包合并的祖先费率来评估它——这个细节以后会要紧。作者还指出了一个隐患:如果替换的各个版本花费了不一致的输入集,两个版本都可能被确认,接收者可能被付了两次。
转折:保护变成了攻击面。 在确立了包是被共同评估的之后,本章引入这样做的代价。追踪相关的未确认交易,所涉及的工作量随允许的亲属数量的平方增长,所以比特币核心把一个包限制在 25 笔交易和 100000 vbytes。作者把这构建成对节点资源的明智防御——然后反转它。同样的这些上限意味着,对手方可以填满你交易的亲属配额,让你无法附加手续费追加。在像闪电网络这样的时间敏感协议中,一个截止时间决定谁保有这笔钱,这就不是一个不便,而是一个可重复的利用,这就是为什么钉住被框定为安全问题,而不是一种烦恼。这里的修辞形状是本章的铰链:作为保障而引入的机制,一经检视,原来就是漏洞。
部分补救,如实标注。 这些修复被呈现为权宜之计,而不是解决办法。CPFP carve out 在通常的限制之外,恰好允许一个额外的小子交易,只能用一次,而且只能用于没有未确认祖先的交易的直接子交易——这个形状恰好适合双方通道,别的更广的都不适合。大多数流行的闪电网络实现采用了围绕它设计的锚点输出模板,而对更多参与者的扩展几乎没有需求。更通用的办法,包中继和短暂锚点,在写作时仍在开发之中。正确地读,这一节是对“钉住已经解决”这种舒适结论的警告。
收尾:两个更安静的事实。 本章从对抗性的协议设计中退后一步,落到原始交易格式的两个性质上。根本没有手续费字段:手续费就是输入超出输出的部分,这意味着被省略的找零输出,会悄悄把余额交给矿工——花费一个 20 比特币的输出去做一笔 1 比特币的付款,又不找零,矿工就收走 19 个。最后是反手续费狙击的惯例:一个重写过去区块的矿工,很想把今天最富的交易拖进去,但如果每个钱包都给它的交易盖上一个等于下一个区块高度的锁定时间,那笔交易在较早的高度上就是无效的,于是重新挖矿的人只能重用当时已经有效的东西,基本上一无所获。两个收尾点都分享了本章底层的教训——手续费是结构性的,而不是声明的,而一个选得好的小小默认值,可以完全去除一种激励。
关键论点,以及支撑它们的原文
手续费是对稀缺区块空间的竞争性出价,而不是固定的价目表。
作者的推理:区块以有限的速率到来,每个区块的空间有限,所以矿工直接纳入他们装得下的付费最高的交易;第9章后面的一切(按费率排名、估算、手续费追加)都从这幅拍卖图景推出。
“几乎所有矿工用来选择把哪些交易纳入其区块的标准,是最大化他们的收入。”
“The criterion that almost all miners use to select which transactions to include in their blocks is to maximize their revenue.”
Transaction Fees查看原文 →
惯例上是花费者,而不是接收者,来付手续费。
顺着拍卖的框架,作者指出,比特币的每一次花费都必须被认证,所以没有花费者同意就不能塞进手续费,而花费者通常是最想快速确认的一方。交易的构造也使承诺一笔手续费不占用额外空间,这使由花费者支付的单笔交易成为最便宜的途径。作者允许存在例外,比如接受未确认付款的商家和预签名的协议。
“在比特币中,每次花费比特币都必须被认证(通常用签名),所以一笔交易不可能在花费者不同意的情况下支付手续费。”
“In Bitcoin, every spend of bitcoins must be authenticated (typically with a signature), so it’s not possible for a transaction to pay a fee without the permission of the spender.”
Transaction Fees › Who Pays the Transaction Fee?查看原文 →
手续费估算永远只能是从近期历史中推断出的近似值。
因为出价是在公开拍卖中设定的,作者论证说没有人能预先知道所需的费率;工具根据最近广播的交易实际多快被确认来推断。他的例子:向节点询问一天的目标(144 个区块),返回一个具体的费率 0.00006570,然而广播之后需求的转移,可能使这个数字出错。
“因为费率是在区块空间的公开拍卖中的出价,所以不可能完美地预测你需要付多少费率,才能让你的交易在某个时间前被确认。”
“Because fee rates are bids in an open auction for block space, it’s not possible to perfectly predict what fee rate you need to pay to get your transaction confirmed by a certain time.”
Transaction Fees › Estimating Appropriate Fee Rates查看原文 →
另外 3 个论点
因为估算会过时,所以需要手续费追加,而 RBF 和 CPFP 在效率与谁被允许追加之间做取舍。
用付费更高的版本替换一笔交易,节省区块空间,但通常需要原签名者,而由接收者驱动的子交易,向任何持有输出的人开放,却要占用额外空间。CPFP 之所以能起作用,是因为矿工按父子捆绑包合并的祖先费率来评估它。作者还警告说,如果替换的各个版本花费了不一致的输入集,两个版本都可能被确认,接收者可能被付了两次。
“与 RBF 相比,CPFP 的主要缺点是它通常会占用更多区块空间。”
“The primary disadvantage of CPFP compared to RBF is that CPFP typically uses more block space.”
Transaction Fees › Child Pays for Parent (CPFP) Fee Bumping查看原文 →
把图景反过来,恰恰是保护节点的那些限制,成了攻击面:钉住可以让对手方偷到钱。
作者先立起了包限制的、保护性的二次成本论证,然后把它转过来:在时间敏感的协议中,如果对手方能把你的一笔交易压到截止时间之后,这个利用就是可重复的,而不是一次性的意外,这就是为什么钉住被当作安全问题,而不只是烦恼。
“如果你的对手方能阻止你的某笔交易在截止时间前确认,他们就可能从你这里偷到钱。”
“If your counterparty can prevent one of your transactions from confirming by a deadline, they may be able to steal money from you.”
Transaction Fees › Transaction Pinning查看原文 →
对预签名协议中钉住的补丁,公认是局部的,所以通用修复的工作仍在继续。
CPFP carve out 只允许在通常的限制之外有一个额外的小子交易,而且不能用两次,所以它只覆盖双方协议。作者指出,大多数流行的闪电网络实现采用了围绕它构建的锚点输出模板,而对更多参与者的扩展几乎没有吸引到需求;更通用的办法,比如短暂锚点,在写作时仍在开发之中。
“不允许多次使用 CPFP carve-out,所以它只适用于双方协议。”
“It’s not allowed to use CPFP carve-out more than once, so it only works for two-party protocols.”
Transaction Fees › CPFP Carve Out and Anchor Outputs查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
作为拍卖的区块空间
单位时间内只出现有限数量的区块,每个区块容纳的空间有限,所以追求收入最大化的矿工,只能装下付费最高的那一组。因此矿工按每单位大小的手续费,而不是总手续费,来给候选交易排名,这把手续费变成了一次竞争性的出价,其获胜水平没人能预先确定。
机制 2
包的限制孕育了钉住
追踪相关的未确认交易,其工作量随允许的亲属数量的平方增长,所以节点把一个包限制在 25 笔交易和 100000 vbytes。这些上限保护了节点,却也让对手方能填满你交易的亲属配额,使你无法在截止时间前附加手续费追加。
机制 3
下一高度的锁定时间钝化了手续费狙击
一个重写过去区块的矿工,很想把今天最富的交易拖回去。如果每个钱包都给它的交易盖上一个等于下一个区块高度的锁定时间,那笔交易在较早的高度上就是无效的,于是重新挖矿的人只能重用当时已经有效的东西,基本上一无所获。
常见误读
CPFP carve out 修好了交易钉住,所以预签名协议现在安全了。
它是一个狭窄的例外:每个包一个额外的小子交易,只能用一次,而且只能用于没有未确认祖先的交易的直接子交易,这适合闪电网络通道这样的双方情形,别的更广的都不适合。作者把它和锚点输出一起呈现为权宜之计,同时更通用的办法,包括包中继和短暂锚点,仍在建设之中。
“不允许多次使用 CPFP carve-out,所以它只适用于双方协议。”
“It’s not allowed to use CPFP carve-out more than once, so it only works for two-party protocols.”
Transaction Fees › CPFP Carve Out and Anchor Outputs查看原文 →
交易带有手续费字段,所以构造时犯的错,最坏也就是付得太少。
根本没有手续费字段——手续费就是输入超出输出的部分,所以被省略的找零输出,会悄悄把全部余额交给矿工。作者的例子:花费一个 20 比特币的输出去做一笔 1 比特币的付款,又不找零,就给了矿工 19 个比特币。
“如果你在手工构造的交易中忘了加找零输出,你就会把找零付作交易手续费。”
“If you forget to add a change output in a manually constructed transaction, you will be paying the change as a transaction fee.”
Transaction Fees › Adding Fees to Transactions查看原文 →
第 9 章的核心概念
- 交易手续费
- 一笔交易留给打包它的任何矿工的钱,为区块空间竞争性地出价。
- 适用处: 不是固定收费;无法对花费者隐瞒,因为每次花费都经过认证。
- 费率
- 手续费除以交易大小/权重,是矿工比较的每单位价格。
- 适用处: 单位各异(聪/vbyte、聪/权重);混用分母可能多付巨额的钱。
- 按手续费替换(RBF)
- 广播同一笔交易的一个付费更高的冲突版本,来追加手续费。
- 适用处: 通常只有原签名者能做;打破了商家对未确认付款的假设。
- 子为父付(CPFP)
- 接收者用一个高手续费的子交易花费一个未确认的输出,使矿工确认两者都有利可图。
- 适用处: 任何持有输出的人都可以用,但它会占用额外的区块空间,并且当父交易低于内存池最低要求时,需要包中继。
- 包中继
- 把父交易和子交易一起中继,使节点能够判断这个包合并后的费率。
- 适用处: 写作时仍在实现;对闪电网络这类预签名的时间敏感协议至关重要。
- 交易钉住
- 后代关系使某人能把替换变得贵得离谱。 对手方填满你交易所允许的亲属包,于是你再也无法附加手续费追加,也就无法及时被确认。
- 适用处: 源于要求为所有被遗忘的后代付费的替换规则。 在像 LN 这样的时间敏感的多方协议中最危险;也可能意外发生。
另外 4 个概念
- 内存池的祖先与后代限制
- 每个包最多 25 笔相关的未确认交易和 100000 vbytes,这样节点才不会淹没在包的重新计算里。
- 适用处: 保护节点资源,但一旦某笔交易后代太多,就会阻止合法的 CPFP 追加。
- CPFP carve out
- 一个特殊的例外,让一笔额外的小子交易(最多 1000 vbytes)加入一个包,即使超出了正常的限制。
- 适用处: 每个包只能用一次,而且只能用于没有未确认祖先的未确认交易的直接子交易,所以只适合双方协议。
- 隐含的交易手续费
- 交易没有手续费字段;手续费就是输入超出输出的部分。
- 适用处: 意味着被遗忘的找零输出会悄悄变成给矿工的小费。
- 手续费狙击
- 矿工重新挖一个过去的区块,把手续费最高的交易从现在拉进被重写的过去。
- 适用处: 当区块补贴占主导时没有利可图;当手续费占奖励的大头时,就变得不可避免。
第 9 章划线与批注AI 陪读
“我们把那个机制称为交易手续费,尽管按这个词通常的意义,它并不是手续费。”
“We call that mechanism transaction fees, although it’s not a fee in the usual sense of that word.”
查看原文 →书停下来,把自己的术语取消命名。聪明——“手续费”引入了固定过路费的错误心智模型,而它其实是连续拍卖中的一次密封出价。
“所以一笔交易不可能在花费者不同意的情况下支付手续费。但可能”
“so it’s not possible for a transaction to pay a fee without the permission of the spender. It is possible”
查看原文 →对比上面的信用卡例子:手续费是隐藏的,因为有别人吸收了它。在这里,签名要求使隐瞒在结构上不可能。透明是密码学的副作用,而不是伦理的副作用。
“我们用“费率”一词,指一笔交易的大小除以权重”
“we use the term fee rate for a transaction’s size divided by weight”
查看原文 →这是错的——应当是手续费除以权重。在定义本章核心单位的唯一一句话里,定义被颠倒了。
另外 14 条批注
“如果他们换成交换分子,理论上他们可能多付 100000000 倍。”
“If they instead switch the numerator, they could theoretically overpay by 100,000,000 times.”
查看原文 →一个数量有六种单位,每一种都是某个过去时刻的化石。这个警告其实是承认,协议的历史作为活生生的财务危险,泄露进了它的用户界面。
“有些商家开始期望这种行为:他们假定,任何支付了合适费率的有效未确认交易,最终都会变成已确认的交易”
“Some merchants came to expect this behavior: they assumed that any valid unconfirmed transaction that paid an appropriate fee rate would eventually become a confirmed transaction”
查看原文 →整个 RBF 争议的根源,是一个习惯被误当成了保证。商家在某一个客户端的实现细节上建立了生意,然后要求协议予以尊重。
“即使比特币核心不是开源的,比特币也是一个可以从头重新实现的开放协议”
“Even if Bitcoin Core wasn’t open source, Bitcoin is an open protocol that can be reimplemented from scratch”
查看原文 →本章最尖锐的一步:在任何人都可以写自己的客户端的系统里,社会期望无法被强制执行。商家没有被冤枉——他们依赖的是一个从未存在过的东西。
“他们没有允许每一笔未确认交易都可被替换(完全 RBF),而是只把比特币核心编程为允许替换那些发出信号表示愿意被替换的交易(选择加入”
“instead of allowing every unconfirmed transaction to be replaced (full RBF), they only programmed Bitcoin Core to allow replacement of transactions that signaled they wanted to allow replacement (opt”
查看原文 →一个妥协,在让出技术论证的同时,保留了输家的舒适。靠默认设置来治理。
“任何保存了该交易版本 0 的矿工,都将能够同时确认它和该交易的版本 2”
“any miner who saved version 0 of the transaction will be able to confirm both it and version 2 of the transaction”
查看原文 →美妙的陷阱。“替换”不是可传递的——冲突是成对的关系,而用户心里那条版本链的模型,悄悄地失灵了。
“爱丽丝现在需要付出比她最初所付多 1000 倍以上的钱,才能用 RBF 为她的交易追加手续费”
“Alice now needs to pay more than 1,000 times as much as she originally paid in order to RBF fee bump her transaction”
查看原文 →反 DoS 规则成了攻击。鲍勃只用一个大的、合法的、完全普通的子交易,就把爱丽丝的交易扣为人质。
“如果你的对手方能阻止你的某笔交易在截止时间前确认,他们就可能从你这里偷到钱。”
“If your counterparty can prevent one of your transactions from confirming by a deadline, they may be able to steal money from you.”
查看原文 →在这里,内存池策略——本应只是本地资源管理——原来承载着真金白银的利害。第二层的安全依赖于非共识的中继启发式,是一堵用惯例造的承重墙。
“不允许多次使用 CPFP carve-out,所以它只适用于双方协议。”
“It’s not allowed to use CPFP carve-out more than once, so it only works for two-party protocols.”
查看原文 →为了拯救某个特定协议,在一条一般规则上凿出的特例例外。作者们把它呈现为补丁而不是设计,很诚实。
“从所有输入中扣除所有输出之后剩下的任何多余金额,就是手续费”
“Any excess amount that remains after all outputs have been deducted from all inputs is the fee”
查看原文 →一种由相减定义、从不声明的手续费。对矿工很优雅,对任何手工构造交易的人则是个陷阱。
“零钱不用找了!”可能不是你本来的意图。”
“Keep the change!" might not be what you intended.”
查看原文 →这个笑话之所以落地,恰恰因为损失是不可逆的。比特币的幽默总是关于你拿不回来的钱。
“他们可以选择把交易从“现在”拉进被重写的“过去”
“they have the option to pull transactions from the "present" into the rewritten "past”
查看原文 →这里最尖锐的一行:重组不只是关于撤销历史,而是关于从未来掠夺它。时间旅行被框定为套利。
“到那时,这种情形将不可避免。”
“At that time, this scenario becomes inevitable.”
查看原文 →对一种理论上的攻击来说,“不可避免”是个强烈的词。作者悄悄地让步,承认比特币安全预算的转移,打破了一个没人解决的假设。
“在正常情况下,这个锁定时间没有任何影响”
“Under normal circumstances, this lock time has no effect”
查看原文 →最好的防御在不用时不花任何代价。一道在有人踩到之前都看不见的绊线。
“当它不干扰钱包对锁定时间字段的其他用途时”
“when it doesn’t interfere with the wallet’s other uses of the lock time field”
查看原文 →这个限定语承认了真正的问题:nLockTime 被重载了。一个字段,好几项冲突的工作——每当碰撞,反狙击就败下阵来。
读后感AI 陪读
第9章看起来像是一章关于为区块空间付费的实用内容,而它一开始就拒绝了自己的标题:我们所称的“手续费”不是过路费,而是对一种稀缺、易逝的商品的连续拍卖中的一次密封出价。这个重新框定是后面一切的钥匙,而本章靠一条不间断的线向外追踪后果来挣得它——从谁来付(花费者,由签名强制执行,所以隐瞒在结构上是不可能的,这是信用卡刷卡费所永远做不到的),到矿工如何给出价排序(费率,其定义句在文中被弄乱成大小除以权重,而它必须是手续费除以权重——在本章承重的单位上一个粗心的失误),再到一个数量有六种相互竞争的计价单位的喜剧,那里关于多付 1 亿倍的警告,其实是承认协议累积的历史,作为活生生的财务危险泄露进了用户界面。
从这里起,本章转向你的出价错了会怎样:RBF 和 CPFP 作为追加手续费,包中继,以及钉住。它最好的一段是关于 RBF 的争议,作者们悄悄拆解了一桩委屈,而不是去仲裁它。商家把某一个客户端的先到先得行为当作了协议保证;既然比特币是一个任何人都可以重新实现的开放协议,在那个层面上就没有任何社会期望能被强制执行。他们没有被冤枉——他们依赖的是一个从未存在过的东西。然而解决办法是选择加入的 RBF:一个默认设置,在让出技术论证的同时保留了输家的舒适。靠配置来治理。本章对替换的锋利边缘也是诚实的——冲突是成对的,不是一条版本链,所以保存了版本 0 的矿工,可以把它与版本 2 一同确认。
继续阅读
钉住的内容,是利害不再停留在理论上的地方。祖先/后代的限制(25 笔交易,100000 vbytes)的存在,是为了限制二次的包更新工作,而同一条反 DoS 规则成了武器:对手方附上一个大的、合法的、极其普通的子交易,爱丽丝现在必须付出她原先手续费的一千倍,才能加价。对闪电网络和其他时间敏感的协议来说,一笔无法在截止时间前确认的交易,就是被偷走的钱。这意味着第二层的安全依赖于内存池策略——非共识的、每个节点各自的中继启发式——一堵用惯例造的承重墙。CPFP carve-out 只能用一次,因此只适用于双方协议,加上锚点输出,被坦率地呈现为补丁,而不是设计。作者们没有把它们打扮起来,值得称赞。
收尾的内容更安静,却同样锋利。手续费是由相减隐含的——输入减去输出,从不声明——这对验证很优雅,对任何手工构造交易的人则是个陷阱;“零钱不用找了!”之所以好笑,只因为损失是不可逆的。而反手续费狙击揭示,重组不只是关于抹掉历史,还关于掠夺它:一个重写历史的矿工可以把高手续费的交易从“现在”拉进被重写的“过去”。把 nLockTime 设为下一个区块高度,是一道踩到之前不花任何代价的绊线——最好的防御——但它是被重载的,一个字段做着好几项冲突的工作,而每当它们碰撞,反狙击就让步。随着补贴下降,“不可避免”这个词用在这种攻击上,是本章最重要的让步:比特币长期安全预算根基上一个未解决的假设。
我要对读者说的是:别把它当作管道工程略读。这里几乎每一个难题——钉住、RBF 的政治、丢失的找零、手续费狙击——都是为一个目的(抵抗 DoS、本地资源管理、验证简单)而写的规则,被对手或经济学挪用成了其作者从未打算的东西。本章真正的主题是策略与共识之间的缝隙,以及有多少真金白银已经坐在了错误的一侧。
在 FeedLitra 里读第 9 章,每段旁边都有这些卡片。
开始读书第 10 章:比特币网络
节点在初始同步时,怎样判定哪条链的工作量证明最多?
第 10 章是怎样展开的AI 辅助
开头:作为政治承诺的架构。 本章开头不是一个协议细节,而是一个关于形状的主张。比特币运行于一个由对等的全节点组成的扁平点对点网络——没有服务器,没有层级,没有特权层。作者的框定之举,是坚持这是去中心化控制的前提条件,而不是工程上的便利,并搬出先例来说明这点:早期互联网,那里的 IP 节点是真正的对等体,以及 Napster 和 BitTorrent 这类文件共享系统。隐含的论证是,权威是由网状结构本身分布的,所以拓扑从不是琐事。从这个前提出发,本章摆出网络的运作部件——节点角色,对等节点发现,全节点怎样同步链——确立后面整章都要拿来衡量的基线参与者。
发展:传播速度,和买更多速度的代价。 摆出了平等是攸关的价值,本章转向在实践中保护它的机制。缓慢的区块传播被表明是一股安静的中心化力量:新区块还在扩散时,有些矿工仍在旧的链尖上延伸,一个竞争区块出现,只有一个存活,而最大的矿工最常赢得这类竞赛。紧凑区块中继以短小的 6 字节交易引用的形式发送区块,由对等节点对照其内存池里已有的东西来核对,从而攻克这一延迟——当发送者对接收者内存池猜得好时,达到理论效率的 97%–99%。作者还为在完全验证之前以高带宽模式转发辩护,理由是伪造工作量证明大约要花 15 万美元,使浪费带宽的攻击不合理;这类对等节点产生的冗余,就是 Bitcoin Core 只允许三个的缘故。然后是对同一逻辑的有意颠倒:私有中继网络把延迟压得更低,但只靠重新引入中心的、受信任的、收费的基础设施——马特·科拉洛 2015 年租用服务器的比特币中继网络,和 2016 年的 FIBRE,用了 UDP、前向纠错和紧凑区块。本章把这当作一个说明了的权衡,用去中心化买来速度,而不是一次测量过的比较。
转折:放弃验证,和随之而来的隐私问题。 本章的枢纽,是从验证一切的节点,转向几乎什么也不验证的客户端。轻量(SPV)客户端用深度替代验证:全节点检查区块 800,000 里的一笔交易,要验证全部 800,000 个区块,而 SPV 客户端通过默克尔路径把交易链到它的区块头,等着区块 800,001 到 800,006 堆在上面,把累积的工作量证明当作检查的代理。作者很小心地说这买来了什么。这样的客户端无法证明有什么东西被扣下没给它,所以必须连到几个随机选的对等节点——而正是这一要求,使它暴露在伪造节点,和整个伪造网络之下。他的陈述条件很直率:要想安全不出岔,没有什么能替代全节点。值得在这里标出深度检查没有确立什么——它表明交易位于一个有人工作过的区块里,而不是不存在冲突的双花,因为证明不存在,需要验证客户端选择跳过的那条链。
转折之后的发展:把过滤器反过来。 隐私的历史被讲成一次失败,随后是一次纠正。在 BIP37 下,客户端把自己的布隆过滤器发给全节点,节点可以在链上重放该过滤器,揭出客户端的地址,而精心构造的过滤器可以迫使节点做大量工作——泄漏加拒绝服务,这就是 Bitcoin Core 最终把布隆过滤器服务限制在明确允许的 IP 地址上的缘故。BIP158 把方向反过来:节点为每个区块建一个紧凑过滤器,存起来,提供给所有人,编码为一个在输出脚本上的戈洛姆-莱斯集,输出脚本经 SipHash 有损地缩成 64 位。客户端现在在本地测试自己的地址,什么也不透露,并可以从不同的对等节点取每个匹配的区块。这种编码保证 100% 的真阳性(偶有假阳性),这使审计成为可能:一个遗漏了客户端后来在该区块里发现的交易的过滤器,就给它的制作者定了罪。客户端还会向几个对等节点取一份 32 字节的承诺,只要那些对等节点不一致,就下载该区块,所以单个不诚实的来源无法误导它们,它们还监视假阳性率有无异常。
收尾:残余的泄漏,和节点自己的簿记。 本章拒绝一个得意的结尾。过滤器缩小了隐私缺口,却没有弥合它——一个监视轻量客户端的流量、或直接与它做对等的对手,可以积累足够多的观察,推断出它的钱包的地址。这个没封上的泄漏,就是提供 Tor 传输的缘故,Bitcoin Core 在能连上本地 Tor 守护进程时,可以自动发布一个隐藏服务。最后一个乐章回到它开头的全节点,现在从里面描述:待处理交易的内存池,为父交易尚未到达的交易准备的孤儿交易池,和共享的 UTXO 数据库。本章于是结束在它开始的地方——完全验证的对等节点——表明了更轻的替代品得到什么,以及精确地给出了什么。
关键论点,以及支撑它们的原文
扁平的点对点设计是去中心化控制的前提条件,而不仅仅是一个方便的工程选择。
作者指出先例,那里平等的参与者撑起了系统:早期互联网,那里的 IP 节点是对等体,以及 Napster 和 BitTorrent 这类文件共享网络。这些例子表明,是架构本身——一张没有服务器或层级的网——在分配权威,这就是比特币采用它、而不是把它当作拓扑琐事的缘故。
“比特币的 P2P 网络架构,远不止是一个拓扑选择。”
“Bitcoin’s P2P network architecture is much more than a topology choice.”
The Bitcoin Network查看原文 →
缩短区块传播时间,是让任何规模的矿工都能竞争的东西,所以紧凑区块中继对去中心化要紧。
当一个对等节点对接收者已持有哪些交易猜对了,一个紧凑区块对一个典型区块能达到理论效率的 97%–99%。作者进一步论证,在完全验证之前以高带宽模式转发是安全的,因为伪造工作量证明大约要花 15 万美元,使浪费带宽的攻击不合理——不过每个这样的对等节点带来的冗余数据,就是 Bitcoin Core 只允许三个的缘故。
“为了防止找块竞赛,并让任何规模的矿工都能平等地参加比特币挖矿这场彩票,把一个矿工宣布新区块、到其他矿工收到该区块之间的时间降到最低,是极其有用的。”
“To prevent block-finding races and allow miners of any size to participate equally in the lottery that is Bitcoin mining, it’s extremely useful to minimize the time between when one miner announces a new block and when other miners receive that block.”
The Bitcoin Network › Compact Block Relay查看原文 →
通过私有中继网络把延迟压得更低,是靠放弃去中心化来买速度。
把上一点掉过来,作者指出这些系统只有靠中心的、受信任的、收费的基础设施才行:马特·科拉洛 2015 年的比特币中继网络运行在租来的虚拟服务器上,2016 年的继任者 FIBRE 加上了 UDP、前向纠错和紧凑区块。文本把这当作一个说明了的权衡,而不是一次测量过的比较。
“前面每一种方法的取舍是,它们在中心化下运作良好,但在去中心化的网络里不行,在那里单个节点不能信任其他节点。”
“The trade-off for each of the preceding methods is that they work well with centralization but not in a decentralized network where individual nodes can’t trust other nodes.”
The Bitcoin Network › Private Block Relay Networks查看原文 →
另外 3 个论点
轻量客户端用交易埋得多深,加上到区块头的默克尔路径,来代替完全验证。
对区块 800,000 里的一笔交易,全节点要检查全部 800,000 个区块;轻量客户端则通过默克尔路径把交易链到它的区块,等着看区块 800,001 到 800,006 堆在上面,把累积的工作量证明当作检查一切的替代。
“轻量客户端只能验证交易存在。”
“A lightweight client can only verify that the transaction exists.”
The Bitcoin Network › Lightweight Clients查看原文 →
顺着那个替代,连接良好的轻量客户端在实践中足够安全,却仍暴露于隐藏交易、网络分割和假对等节点。
由于这样的客户端无法证明有什么被扣下没给它,作者推论它必须连到几个随机选的对等节点——而正是这需要随机选对等节点的情形,使它暴露在伪造节点和整个伪造网络之下。作者陈述的条件:要想安全不出岔,没有什么能替代运行一个全节点。
“对许多实际用途而言,连接良好的轻量客户端足够安全,在资源需求、实用性和安全之间取得了平衡。”
“For many practical purposes, well-connected lightweight clients are secure enough, striking a balance between resource needs, practicality, and security.”
The Bitcoin Network › Lightweight Clients查看原文 →
早先的 BIP37 布隆过滤器做法不得不放弃,因为它泄漏客户端地址,并招来拒绝服务。
一个全节点拿到客户端的布隆过滤器,可以把该过滤器在链上回放,揭出客户端在找什么,而精心构造的过滤器迫使节点做大量工作。出于这两个原因,Bitcoin Core 最终把布隆过滤器服务限制在明确允许的 IP 地址上——这次失败,推动了接下来描述的、反过来由服务器构建的过滤器设计。
“收到对等节点布隆过滤器的全节点,可以把该过滤器用在整条区块链上,找出客户端的所有交易(外加假阳性)。”
“A full node receiving a bloom filter from a peer could apply that filter to the entire blockchain to find all of the client’s transactions (plus false positives).”
The Bitcoin Network › How Lightweight Clients Use Bloom Filters查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
为什么快速区块中继帮助小矿工
如果一个新区块传得慢,有些矿工就继续在旧链尖上构建,出现一个竞争区块;只有一个存活,而最大的矿工最常赢得这类竞赛。紧凑区块中继以 6 字节的短交易引用发送区块,对等节点把它们同内存池里已有的交易匹配,从而削减了延迟。
机制 2
把过滤器掉个头来保护地址
在旧方案下,每个客户端把自己的模式过滤器发给全节点,节点可以在链上重放它,得知客户端的地址。把方向反过来,让节点为每个区块建一个过滤器,存下来并提供给所有人,客户端就在本地测试自己的地址,什么也不透露,甚至可以从不同的对等节点取每个匹配的区块。
机制 3
客户端怎样抓住一个撒谎的过滤器
因为紧凑编码保证区块里真有的任何东西都会被标出,一个遗漏了客户端后来在该区块里发现的交易的过滤器,就给制造者定了罪。客户端还向几个对等节点取一份 32 字节的承诺,只要对等节点不一致,就下载该区块,所以单个不诚实的来源无法误导它们。
常见误读
既然轻量客户端检查了默克尔路径和六个确认,它基本上已经验证了这笔付款有效。
这个检查确立的,只是交易存在于一个堆了工作量的区块里。这样的客户端无法证明不存在冲突交易,比如双花,因为证明不存在,需要验证链本身——那恰是它跳过的工作。
“轻量客户端只能验证交易存在。”
“A lightweight client can only verify that the transaction exists.”
The Bitcoin Network › Lightweight Clients查看原文 →
一旦钱包改用服务器生成的紧凑区块过滤器,轻量客户端就不再泄漏信息,变得同全节点一样私密。
过滤器缩小了缺口,却没有弥合它:一个监视轻量客户端的流量、或直接与它做对等的对手,可以积累足够多的观察,推断出哪些地址属于它的钱包。这个残余的泄漏,就是本章提供 Tor 作为传输的缘故,Bitcoin Core 能连上本地 Tor 服务时,可以自动发布一个隐藏服务。
“轻量客户端的隐私比全节点弱。”
“Lightweight clients have weaker privacy than a full node.”
The Bitcoin Network › Lightweight Clients and Privacy查看原文 →
第 10 章的核心概念
- 点对点网络架构
- 一个由对等节点组成的网,没有服务器或层级,每个节点既提供服务也消费服务。
- 适用处: 描述比特币的 P2P 协议层;矿池和轻量钱包用其他更中心化的协议,由网关服务器衔接。
- 紧凑区块中继
- 把新区块以 6 字节的短交易标识符发送,让对等节点复用它们内存池里已有的交易。
- 适用处: 并不缩小区块;一个没有先前内存池信息的节点,仍须下载完整的区块。
- 找块竞赛
- 一个矿工在听到新区块之前,在旧链尖上构建,造成两个竞争区块;只有一个存活。
- 适用处: 偏向最大的矿工,所以与去中心化相悖;靠更快的区块传播缓解,而不是消除。
- 全节点验证
- 独立验证最多工作量证明链的每个区块里的每笔交易,从创世区块起。
- 适用处: 需要处理整条链;归档全节点还额外保存完整副本,为轻量 SPV 客户端提供服务。
- 网络发现
- 一个启动的节点怎样找到对等节点:DNS 种子或给定的种子节点,version/verack 握手,然后 addr 和 getaddr 交换。
- 适用处: 地理位置无关,一个连接就够;连到的节点超过少数几个,就是浪费资源。
- 简化支付验证(SPV)
- 靠区块头的工作量证明和埋藏深度来验证一笔交易,而不是验证每个区块。
- 适用处: 证明一笔交易存在,却无法证明一笔冲突交易(如双花)不存在。
另外 8 个概念
- 布隆过滤器
- 一种概率模式过滤器,阳性匹配意味着也许,阴性匹配意味着肯定不是。
- 适用处: 随着更多模式使位数组饱和,精度衰减;实践中它泄漏隐私,也招来拒绝服务。
- 紧凑区块过滤器
- 节点为每个区块建的一个过滤器,客户端用自己的地址去测试它,下载整个匹配的区块。
- 适用处: 只覆盖已确认的交易,让客户端多花带宽,而且无法仅凭区块验证。
- 戈洛姆-莱斯编码集(GCS)
- 把一个排序列表无损地编码为差值,常见的小间隔用短码。
- 适用处: 收益取决于数值在固定范围内随机分布,使差值保持很小。
- 有损编码
- 把每个输出脚本哈希成一个 64 位值,丢弃数据以省空间。
- 适用处: 只有接受非零的假阳性率才省空间;不是密码学承诺。
- 假阳性率
- 过滤器标出的、里面没有钱包关心之物的区块所占的份额。
- 适用处: 只花带宽,甚至可以帮助隐私;它从不隐藏真正的匹配。
- 内存池
- 节点暂存的、尚未进入区块的有效交易列表。
- 适用处: 本地的、节点特有的;不像 UTXO 集,它不是涌现的共识。
- 孤儿交易池
- 存放父交易仍未知的交易的暂存区。
- 适用处: 只有一些实现保留一个;父交易到达后,条目就离开。
- 未花费交易输出(UTXO)
- 所有从未被花过的币,作为网络共享的状态存在磁盘上。
- 适用处: 反映全网共识,所以不应在节点之间不同。
第 10 章划线与批注AI 陪读
“寻找区块的竞赛让最大的矿工占优势,所以它们的作用与比特币根本的去中心化背道而驰”
“Block-finding races give the advantage to the largest miners, so they act in opposition to Bitcoin’s essential decentralization”
查看原文 →整个紧凑区块一节的真正赌注在这里:它不是带宽优化,而是反寡头措施。延迟是政治的。
“由于工作量证明生成起来很贵(写作时约15万美元),矿工不太可能为了浪费中继节点的带宽而伪造它”
“Since proof of work is expensive to generate (about $150,000 USD at the time of writing), it’s unlikely that a miner would fake it just to waste the bandwidth of relay nodes”
查看原文 →可爱的推理:不去验证,而是把攻击定价挤出去。信任被成本估算取代——这也意味着安全边际随市场漂移。
“前面每种方法的权衡是,它们在中心化下运作良好,而在去中心化的网络里就不行,因为在那里各个节点不能信任其他节点”
“The trade-off for each of the preceding methods is that they work well with centralization but not in a decentralized network where individual nodes can’t trust other nodes”
查看原文 →诚实的承认。本章刚教的每一个提速招数都需要信任——而矿工,这本是要保护他们免受巨头压制的人,恰恰是运行 FIBRE 的人。
另外 14 条批注
“没有地图的游客最好的机会,是多问些人,希望其中有些人不是想抢他”
“The mapless tourist’s best chance is to ask enough people and hope some of them are not trying to mug him”
查看原文 →这个玩笑成立,因为它是字面的:简化支付验证的安全,真的就是“多问足够的陌生人”。可喜的是,这个类比最弱的一点,也是协议最弱的一点。
“轻量客户端当然可以验证一笔交易存在,却无法验证一笔交易不存在,比如对同一个 UTXO 的双花”
“A lightweight client can definitely verify that a transaction exists but cannot verify that a transaction, such as a double-spend of the same UTXO, doesn’t exist”
查看原文 →证明的不对称——存在可以证明,不存在不能。这就是全节点要紧的全部缘由,一个分句说完。
“布隆过滤器的阳性匹配是“也许,是的”。”
“a bloom filter positive match is a "Maybe, yes.”
查看原文 →这个不对称就是整个招数:确定性只以否定的形式到来。比特币到处都倚靠这个形状——你能证明没有匹配,却永远证明不了有。
“这样的问题,对想去的目的地透露得略少一点”
“A question like that reveals slightly less about the desired destination”
查看原文 →“略”字在这里承重很大,而后面的小节也承认了——这个类比兜售的隐私,机制从没兑现。
“后来变得清楚,它们并没有提供多少隐私”
“it became clear that they didn’t offer very much privacy”
查看原文 →八年的 BIP37 钱包,是建立在一个在一次显而易见的攻击下就溶解的隐私承诺上出货的:只要把过滤器在整条链上跑一遍。没有人事先试过。
“把布隆过滤器的过程反过来”
“reversing the bloom filter process”
查看原文 →漂亮的颠倒——谁做哈希、谁做匹配,决定谁握着信息。同样的数学,相反的权力关系。
“如果我们牺牲次要目标,就有更高效的办法来达成主要目标”
“more efficient way to accomplish the primary goal if we sacrificed the secondary goal”
查看原文 →对这个取舍很坦率:他们为了体积放弃了可验证性,然后花整整一节,用多对等节点轮询来补这个洞。诚实的工程,明显不完美。
“任何想要最好隐私的人,仍应使用自己的全节点”
“anyone wanting the best possible privacy should still use their own full node”
查看原文 →两代过滤器之后,副歌不变。所有这些巧思,只是缩小了一个它没法弥合的缺口。
“多数新的比特币用户以为,比特币节点的网络通信是加密的。”
“Most new users of Bitcoin assume that the network communications of a Bitcoin node are encrypted.”
查看原文 →一句话里丢下的安静的炸弹。在几页概率隐私的精细调校之后,线路本身是明文的。
“这笔孤儿交易会被暂时存放在孤儿交易池里,直到父交易到达”
“the orphan transaction will be stored temporarily in the orphan pool until the parent transaction arrives”
查看原文 →注意缺了什么:没有说明驱逐策略。一个等着可能永不到来的父交易的池,是现成的内存耗尽向量——真实的客户端把它严格封顶,而文本略过了这一点。
“这个过程被递归地重复,寻找任何更多的后代,直到再找不到后代为止”
“the process is repeated recursively looking for any further descendants until no more descendants are found”
查看原文 →递归是优雅的部分:一次到达,可以解开一条任意深的链。这也意味着交易在线路上的顺序真的无所谓——网络对自己的无序有韧性。
“让孤儿与它们的父交易沿着整条链一路团聚”
“reuniting the orphans with their parents all the way down the chain”
查看原文 →家庭比喻整节都在安静地做着活——孤儿,父,子,后代——在这里作者让它绽放。温暖,但它在只有哈希匹配的地方,夹带了意图。
“一直回溯到创世区块的一切未花费的东西”
“everything that is unspent from all the way back to the genesis block”
查看原文 →唯一一个字面上是累积历史的数据库。每一枚至今未花的币都在一张表里——包括中本聪从没动过的那些。
“UTXO 数据库代表网络涌现出的共识,因此通常不会在节点之间变化”
“the UTXO database represents the emergent consensus of the network and therefore will not usually vary between nodes”
查看原文 →这是本章最锐利的一句话,由“通常不会”这个留有余地的说法来承担。内存池是意见,UTXO是事实——可那个事实只是推导出来的,而在重组期间,节点会就现实本身短暂地产生分歧。
读后感AI 陪读
第10章读起来像一次网络层的巡礼,可从头到尾跟下来,它其实是围绕单一权衡的一场持续论证:让比特币变得快、便宜或轻量的一切,都要拿信任来付,而本章分期付着这笔代价,每次都老实说出价格。它开头是对等节点组成的扁平网状——没有层级,没有特殊节点,角色只由每位运营者选择存什么、做什么来区分。这幅平等主义的图画立刻被物理学弄复杂了:区块传播需要时间,最先听到的矿工赢更多竞赛。所以紧凑区块中继和基于前向纠错的私有中继网络出现,不是作为带宽调优,而是作为反寡头工程。延迟是政治的,本章知道这一点。那个被承认而不是被隐藏的转折是,最快的中继方案假定参与者是合作的、受信任的——而这些方案本想保护、使之免受巨头压制的矿工,恰恰是造出并运行它们的人。去中心化的辩护,本身就是一个小小的中心化。
中间的乐章——自举,先区块头同步,然后是轻量客户端——在钱包层面做同样的动作。简化支付验证用放弃全节点有的那一样东西来换取廉价:知道什么没有发生的能力。存在可以通过默克尔路径证明;不存在则不能。这一个不对称,就是本章的结构脊梁,它以令人惊异的规律不断重现。布隆过滤器的“是”是“也许”,只有它的“否”才是确定的。紧凑过滤器保证真阳性,容忍假阳性。在这套系统里,确定性几乎总是以否定的形式到来,而一旦你想要肯定的保证,你就需要整条链。
继续阅读
过滤器的历史是最有教益的一段,应该把它当作警世故事来读,而不是功能清单。BIP37 在一个隐私主张上上线了将近十年,而这个主张在你能想到的最明显的攻击下垮了——拿客户端自己的过滤器在整条链上跑一遍,看着钱包暴露自己——同时还把一个廉价的拒绝服务向量送给了服务器。修复颠倒了谁做哈希、谁做匹配:服务器发布一个在区块内容上的戈洛姆-莱斯编码集,客户端在本地测试。同样的数学,相反的权力关系;这个颠倒,而不是压缩,才是真正的想法。可是这个颠倒付出了可验证性的代价,因为一个你没有自己构建的过滤器,是你必须凭信仰接受的过滤器,所以本章又花一节来修补这个洞:跨对等节点比对 32 字节的承诺,并监控假阳性率。这是诚实的工程,明显不完美——一个概率结构,由一个社会结构守着。而在两代过滤器之后,副歌一个字没变:想要真正的隐私,就运行你自己的节点。所有这些巧思,缩小了一个它没法弥合的缺口。
然后是安静的炸弹,它重新框定了它上面的一切:多数用户以为节点的流量是加密的,而它不是。几页精心的概率隐私调校,坐在一条明文的线路上,Tor 被当作外挂的补救。值得停下来想想这个顺序——本章通过过滤器来调节那个泄漏,而管道本身是敞开的——因为它显示了协议隐私在实践中是怎样建起来的:局部地,渐进地,很少从威胁模型往下做起。
关于节点数据的收尾小节转向内部,也是本章最机灵的话藏身之处。内存池是意见,临时的,按设计就有分歧。孤儿交易池是候诊室,它把到来的父交易和存着的子交易递归地重新团聚,真正优雅:一笔交易可以解开一条任意深的链,这意味着网络容忍自己的无序,线路上的排序根本无所谓。但请注意那个遗漏——对一个可能永远在等父交易、而父交易永不到来的池,没有说明驱逐策略,这是教科书式的内存耗尽向量,真实的实现会把它严格封顶。文字温暖的地方,也略显松散:孤儿/父/子/后代的比喻起了真正的说明作用,随后又在只有哈希匹配的地方,夹带进了意图。UTXO 集是平衡砝码——累积的历史,从创世以来每一枚未花费的币都在一张表里,包括中本聪从没动过的那些——并被描述成“通常不会在节点之间变化”的涌现的共识。那个留有余地的说法是本章最锐利的东西。UTXO 集是比特币最接近事实的东西,然而它只是推导出来的,而在重组期间,节点会就现实本身短暂地产生分歧。
我会对读者说的:别把这一章当作优化的目录来读。把它当作一本账来读,看每个优化向信任借了什么,并检查书里有没有说出放贷的是谁——它通常说了,在一个从属分句里,而那恰是真正的内容所在。有两个习惯会对你有用。第一,每当一个机制许诺隐私或效率,就问它能证明什么、只能暗示什么;可证明的存在与不可证明的不存在之间的不对称,会解释大部分设计。第二,留意那些留有余地的说法和成本估算——“略少”,“通常不会”,“约15万美元,所以不太可能”——因为安全就是在那里被悄悄从保证换成概率或市场价格的,而价格是会漂的。本章反复的建议——运行你自己的节点——不是纯洁性的仪式;它是你不再借用的那唯一一种配置。
在 FeedLitra 里读第 10 章,每段旁边都有这些卡片。
开始读书第 11 章:区块链
节点如何在争夺同一高度的两个区块之间做选择?
第 11 章是怎样展开的AI 辅助
开篇:作为链的链。 第11章以一个承担了后面所有工作的定义开篇:区块链是一摞区块,每个区块头都携带前一个区块的哈希。从这一个链接,作者推出了本章的核心性质。编辑旧区块中的任何东西,它的哈希就变了;指向旧哈希的子区块就不再指向任何有效的地方,所以子区块必须被重建,然后是孙区块,然后是此后的每个区块,每个都要重新计算工作量证明。因此,永久性不是协议里的规则,而是算术的后果——作者小心地区分了这一点。他把链比作地质地层的意象,最新的六个区块是松散的表土,深层几乎未受扰动,被作为一幅图景提供,而不是风险计算。没有什么禁止一条更长的链取代现有的东西;深度只是把概率推向零。币基奖励 100 个区块的成熟规则,是同一逻辑的操作化:它买到的是可忽略的风险,而不是不可能。
展开:给区块命名,并证明其中有什么。 在这个结构的基础上,本章走过实际的机制。一个区块的标识符是它 80 字节区块头的哈希,它属于那个区块,不属于其他任何区块;而高度,相比之下,只是从创世区块起位置的计数,两个竞争的区块完全可以共用一个编号。作者用一个里程碑来锚定这个抽象——链在 2023 年年中越过了 800000 的高度,从 2009 年 1 月开始往上数——然后转向默克尔树。这里的回报是压缩。把交易两两哈希沿着一棵二叉树往上,在区块头里留下一个 32 字节的根,成员资格然后只需要沿着单个分支的兄弟哈希就能证明,大约 log₂(N) 个。他的图用四个哈希证明了交易 K,128 字节;放大到一个包含约 16000 笔交易的 4000000 字节的区块,证明就是那笔交易、一个 80 字节的区块头,加上 448 字节的路径——比它所证明的东西小大约一万倍。把区块的交易数量翻倍,只增加恰好一个哈希。作者没有让这份优雅不加限定地过去:因为比特币通过复制最后一个哈希来补齐奇数行,列表 [1,2,3,4,5,6] 和 [1,2,3,4,5,6,5,6] 塌缩到同一个根。那就是 CVE-2012-2459,比特币核心通过拒绝把两个相同的末尾哈希哈希在一起的区块来绕过它。匹配的根是内容的有力证据,而不是对内容的完整钉死。
转折:从链如何运作,到在哪里试它。 本章转向比特币的测试网络,而这个转向不只是结构上的——它检验本章自己的前提。Testnet3 完全复制主网无许可的工作量证明,却有意剥去了币的价值,而这一个减法,拆解了安全论证所依赖的激励。如果手续费不给矿工买到任何东西,剩下的唯一理由去纳入陌生人的交易,就是善意。没有善意的矿工,可以一个接一个地挖空区块,把用户无限期地挡在外面。机制幸存;动机则没有。
答案,及其价格。 Signet 的回应,是放弃 testnet3 所保留的东西:区块只有在被授权方签名时才算数。作者明确指出,这笔交易在主网上将是无法容忍的,只有在币一文不值的地方才站得住——有许可的授权是让步,而不是改进。作为交换,它管用。默认的 signet 在约一个 GB 里带着大约 150000 个区块,支持每一个主网特性,并承载着 Bitcoin Inquisition 的升级测试;而且因为 BIP325 的 signet 搭起来很便宜,任何对某个 signet 的运营方式不满意的人,可以直接运行自己的,这让许可制不至于硬化成控制。
收尾:一条分阶段的流水线。 本章以实用建议结束,把三个网络折成一个序列。Regtest 排第一——一条从零开始的私有链,挖矿是瞬时的,通过一次几秒钟挖出 500 个区块、最后得到一个可花费的 12462.50000000 的演练来展示,与完整的 500 个之间的差距,由 100 个区块的成熟规则解释,只留下 400 个区块的奖励可用。这种速度赢得了 regtest 的第一个位置,但它的封闭恰恰是它不能排最后的原因:只遇到过私有链的代码,还没有遇到过公共对等节点。因此是 regtest,然后 signet 或 testnet,然后主网——每次改动一遍。于是本章把它开篇的主题交还到读者手中:链很难改写,这恰恰就是为什么你想先在别处犯下你的错误。
关键论点,以及支撑它们的原文
一旦一个区块上面叠了许多区块,改写它就变得不切实际,而不只是昂贵。
作者推理了这个级联:改动父区块,迫使其子区块有一个新哈希,又迫使孙区块有一个新哈希,一路沿链而下,所以所有那些工作都得重做。他把链描绘成地质地层——最新的六个区块是松散的表土,而深层几乎从不被扰动——不过他把这呈现为一幅图景,而不是风险计算。
“这个序列确保,一旦一个区块后面跟着许多代,不迫使重新计算所有后续区块,就无法改变它。”
“This sequence ensures that, once a block has many generations following it, it cannot be changed without forcing a recalculation of all subsequent blocks.”
The Blockchain查看原文 →
在这个链结构的基础上,区块的哈希唯一地给它命名,而它的高度则不然。
哈希由 80 字节的区块头算出,只属于一个区块;高度只是从创世区块起位置的计数,两个竞争的区块可以占同一个编号。作者用一个具体的里程碑来锚定高度的概念:链在 2023 年年中越过了 800000 的高度,从 2009 年 1 月的第一个区块往上数。
“一个区块的区块哈希总是唯一地标识一个区块。一个区块也总是有一个特定的区块高度。然而,并不总是一个特定的区块高度就标识单个区块。”
“A block’s block hash always identifies a single block uniquely. A block also always has a specific block height. However, it is not always the case that a specific block height identifies a single block.”
The Blockchain › Block Identifiers: Block Header Hash and Block Height查看原文 →
默克尔树让任何人都能以随着区块变大几乎不增长的成本,证明一笔交易在某个区块里。
在作者的图里,交易 K 用四个 32 字节的哈希——共 128 字节——被证明属于它的区块。放大来看,对一个 4000000 字节区块中约 16000 笔交易之一的证明,需要交易本身、80 字节的区块头,和 448 字节的路径,比它所证明成员资格的区块小大约一万倍。
“不管区块里有一笔交易还是一万笔交易,默克尔根总是把它们概括成 32 个字节。”
“Whether there is one transaction or ten thousand transactions in the block, the merkle root always summarizes them into 32 bytes.”
The Blockchain › Merkle Trees查看原文 →
另外 3 个论点
从链如何运作转到在哪里测试它:testnet3 继承了主网的开放挖矿,却没有它的激励,所以怀有敌意的矿工能让它无法使用。
因为测试网的币本应一文不值,手续费不给矿工任何东西,剩下的唯一动机去纳入用户交易,就是善意。一个不具备那种善意的矿工,可以连续挖许多区块而不带任何人的交易,把用户挡在外面。
“这意味着捣乱的矿工可以在测试网上连续创建许多区块,而不包含任何用户交易。”
“That means disruptive miners can create many blocks in a row on testnet without including any user transactions.”
The Blockchain › Testnet: Bitcoin's Testing Playground查看原文 →
Signet 通过放弃无许可挖矿来回答这一失败:区块只有在被授权方签字认可时才算数。
作者指出,这笔交易在主网上将是不可接受的,只有在币没有价值的地方才站得住。他指出默认的 signet 已经在大约一个 GB 里带着约 150000 个区块,支持每个主网特性,并承载 Bitcoin Inquisition 的升级测试——而且由于 BIP325 的 signet 启动起来很便宜,任何对某个 signet 的运营方式不满意的人,可以启动自己的。
“比特币中的挖矿是无许可的——任何人都可以做——而 signet 上的挖矿是完全有许可的。”
“Whereas mining in Bitcoin is permissionless—anyone can do it—mining on signet is fully permissioned.”
The Blockchain › Signet: The Proof of Authority Testnet查看原文 →
实际的结论是一条分阶段的流水线:先在 regtest 上测试,然后 signet 或 testnet,然后主网,每次改动一遍。
Regtest 是一条从零开始建立的私有链,挖矿是瞬时的——作者的演练在几秒钟内挖出 500 个区块,最后得到一个可花费的 12462.50000000,因为币基奖励需要 100 个区块的深度,只有 400 个区块的奖励成熟了。这种速度使它成为第一阶段,但因为它是封闭的,代码之后仍必须面对公共对等节点。
“你可以使用测试区块链来建立一条开发流水线。”
“You can use the test blockchains to establish a development pipeline.”
The Blockchain › Using Test Blockchains for Development查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
哈希链接锁住过去
每个区块头都携带其父区块的哈希,所以编辑旧区块会改变它的哈希,使指向它的子区块失效。伪造者然后必须重做子区块、孙区块,以及此后的每个区块,重新计算它们所有的工作量证明——这就是为什么是深度,而不是任何规则,让旧历史实际上固定不变。
机制 2
默克尔根缩小证明
一个区块中的所有交易,沿着一棵二叉树两两哈希,直到一个 32 字节的根坐落在区块头里。要表明一笔交易在里面,你只需提供沿着它的分支的那几个兄弟哈希,大约 log2(N) 个,然后重新计算根——所以交易数量翻倍,只给证明增加一个哈希。
机制 3
一文不值的币破坏了挖矿的激励
比特币的挖矿安全假定,手续费和奖励付钱给矿工,让他们为用户服务,但测试网的币有意是毫无价值的,所以手续费什么也买不到。剩下的唯一理由去纳入某人的交易,就是善意,而没有善意的矿工,可以一个接一个地挖空区块,让网络一直无法使用。
常见误读
埋在链深处的区块被永久锁定了——协议根本不会让它们被替换。
规则里没有任何东西禁止这样做:更长的链总是可以取代现有的区块,而深度只是把这种可能性推向零。这就是为什么作者把旧历史框定为实际上而非绝对地不可改变,也是为什么币基奖励要等 100 个区块的规则,是关于让逆转的风险可以忽略,而不是不存在。
“这个序列确保,一旦一个区块后面跟着许多代,不迫使重新计算所有后续区块,就无法改变它。”
“This sequence ensures that, once a block has many generations following it, it cannot be changed without forcing a recalculation of all subsequent blocks.”
The Blockchain查看原文 →
匹配的默克尔根,意味着区块必定包含恰好那一份交易列表,所以根把内容完全钉死了。
比特币通过复制最后一个哈希来补齐奇数个哈希,作者表明列表 [1,2,3,4,5,6] 和 [1,2,3,4,5,6,5,6] 产生相同的根——这是 CVE-2012-2459 背后的缺陷。比特币核心不得不通过拒绝把两个相同的末尾哈希哈希在一起的区块来绕过它。
“这导致某些交易序列产生同一个默克尔根。”
“This results in certain sequences of transactions leading to the same merkle root.”
The Blockchain › Merkle Trees查看原文 →
第 11 章的核心概念
- 哈希承诺
- 每个区块头通过前一个区块哈希承诺于它的父区块,所以改动任何旧区块都会迫使重新计算此后的每一个区块。
- 适用处: 承诺使改写变得昂贵,而不是不可能:更长的链总是可以撤销区块。
- 区块头哈希
- 区块的主要 ID:仅对其 80 字节区块头做的双重 SHA256,由每个节点重新计算,而不是存储在区块里面。
- 适用处: 每个区块唯一,不像区块高度,两个竞争的区块可以共用。
- 区块高度
- 区块的位置,从高度为 0 的创世区块起算。
- 适用处: 不是唯一标识符;两个或更多区块可以竞争同一个高度。
- 创世区块
- 第一个区块,被静态编码在比特币核心里,所以每个节点都从相同的可信根出发。
- 适用处: 它是硬编码的,所以从不像其他区块那样被验证或下载。
- 默克尔树
- 一棵双重 SHA256 哈希的二叉树,把一个区块的所有交易压缩成区块头里一个 32 字节的根。
- 适用处: 比特币对奇数个末尾哈希的复制,导致了 CVE-2012-2459,需要特殊的防御。
- 默克尔路径
- 大约 log2(N) 个哈希,让任何人能从一笔交易重新计算出默克尔根,证明它在区块里。
- 适用处: 证明被包含在某个区块里,而不是该区块在最佳链里;后者由区块头的链接提供。
另外 4 个概念
- 成熟规则
- 币基奖励只有在 100 个区块之后才可花费,到那时重组风险已可忽略。
- 适用处: 深度降低、但从不使逆转的可能性归零。
- 测试网
- 一个功能齐全的并行比特币网络,其币本意就是一文不值,用来安全地测试软件。 一个测试网络,其中每个区块都必须带着证明,表明一个可信的权威批准了它。 一条从零开始、用于私下测试的本地封闭区块链,区块可以被瞬间挖出。
- 适用处: Testnet3 仍然超过 30 GB,所以并不轻量;它的地址使用不同的前缀。 只在币没有价值的测试网上可以接受;这样的许可制在主网上会被拒绝。 不是公开或共享的,所以无法让代码接触到各种各样的真实世界对等节点和应用。
- 挑战脚本
- 自定义 signet 用来决定一个区块是否被授权的标准比特币脚本。
- 适用处: 只有自定义 signet 才需要;默认 signet 不需要这样的参数。
- 工作量证明
- 依赖手续费和奖励激励来让矿工为用户服务的挖矿安全。
- 适用处: 在禁止币拥有价值的地方,它的激励逻辑就崩溃了。
第 11 章划线与批注AI 陪读
“因为这样的重新计算需要巨大的计算量(因此也需要巨大的能耗),一条长长的区块链的存在,使得改动区块链的深处历史变得不切实际”
“Because such a recalculation would require enormous computation (and therefore energy consumption), the existence of a long chain of blocks makes the blockchain’s deep history impractical to change”
查看原文 →注意这个诚实的词:不切实际,而不是不可能。比特币的安全是经济性的,而不是数学性的——一张价签,不是一把锁。
“最上面的六个区块就像几英寸的表土。”
“The top six blocks are like a few inches of topsoil.”
查看原文 →冰川岩芯的比喻做了实事,但夹带了虚假的宽慰:地质靠物理稳定,链只靠持续的开销稳定。一旦停止付钱,“几百万年”就融化了。
“区块高度并不总是标识单个区块”
“the block height does not always identify a single block”
查看原文 →安静的承认:“链”是个方便的虚构——在链尖有好几条链,高度是一种主张,而不是一个地址。
另外 12 条批注
“请记住,下面的默克尔树算法有一个与重复 txid 相关的严重缺陷”
“keep in mind that the following merkle tree algorithm has a serious flaw related to duplicate txids”
查看原文 →一块被它自己的机制钉在机器内部的警示牌。一本协议书引用一条写着“别在这里抄我们”的源码注释,很少见。
“它将无法再接受同一区块的其他未经修改的(因而可能有效的)版本”
“it will fail to accept further unmodified (and thus potentially valid) versions of the same block”
查看原文 →优雅的攻击形态:你不伪造区块,你毒害节点对区块的记忆。防御是设计缺陷之上的一个补丁,而不是对它的修复。
“这使得最大可能的证明,比最大可能的比特币区块小了将近 10000 倍。”
“That makes the largest possible proof almost 10,000 times smaller than the largest possible Bitcoin block.”
查看原文 →本章真正的魔法在这里,而不在哈希里:对数,才使弱者的验证成为可能。
“交易仍然包含所谓的手续费,但这些手续费没有任何经济价值”
“transactions still contain something called fees, but those fees don’t have any economic value”
查看原文 →Testnet 是最干净的证明,表明比特币不是一种数据结构,而是一种激励结构——去掉钱,同样的代码就不再起作用了。
“这对比特币主网来说将是完全不可接受的改动——没有人会使用那样的软件”
“This would be a completely unacceptable change to Bitcoin’s mainnet—no one would use that software”
查看原文 →Signet 悄悄承认,无许可是你为价值付出的代价,而不是其本身的美德。在没有什么利害攸关的地方,权威只是更方便。
“它目前由该项目的两位贡献者运营。”
“It is currently operated by two contributors to that project.”
查看原文 →两个人决定哪些区块有效。直白地陈述,没有评论——但这是坐在一本讲无需信任的书里的信任假设。对测试台来说没问题,仍然值得注意。
“我们一般建议,挖矿软件的公开测试在 testnet3 上进行”
“we generally recommend that the public testing of mining software occur on testnet3”
查看原文 →挖矿软件被流放到 testnet3,恰恰因为 signet 去掉了真正的挖矿。修复了混乱的沙盒,再也无法测试混乱的那一部分。
“币基奖励必须深入 100 个区块,你才能花费它们”
“coinbase rewards must be 100 blocks deep before you can spend them”
查看原文 →即使在一条你绝对掌控的假区块链里,成熟规则仍然咬人。共识规则不在乎你一个人在房间里。
“12462.50000000”
查看原文 →一个在主网上会改变人生的数字,在这里却一文不值。金钱的全部价值,压缩进了一个配置标志。
“挖出所有这些区块只需要几秒钟”
“It will only take a few seconds to mine all these blocks”
查看原文 →难度接近 4.6e-10——工作量证明还在,只是调到了近乎零。优雅:机制没变,只是旋钮动了。
“再次启动流水线,先在 regtest 上部署每项改动,然后是 signet 或 testnet”
“start the pipeline again, deploying each change first on regtest, then on signet or testnet”
查看原文 →这四条链原来不是四个稀奇物,而是一架梯子,每一级买到不同种类的真实感。这套分类学,其实一直是暗中的方法论。
“那个同时提供计算安全性、并确保没有区块可以被改动的特殊承诺”
“the special commitment that both provide computational security and ensure no block can be changed”
查看原文 →漂亮的支点:迄今为止的一切,都是靠廉价的哈希拢在一起的结构。挖矿才使改写它变得昂贵。链接是免费的;锚定要花钱。
读后感AI 陪读
第11章看起来是全书最结构性的一章——哈希、区块头、默克尔树、测试网络——而这恰恰是应该逆着纹理来读它的方式。它以后向链接的链,和深处的历史“不切实际”去改动的主张开篇,而那个诚实的形容词,为后面的一切定了调:比特币的不可变性是一张价签,不是一把锁。本章提供的冰川岩芯比喻既美丽,同时又略有误导,因为冰是由物理稳定的,而链仅仅由持续的开销来稳定;一旦停止付钱,几百万年就会融化。承认区块高度并不总是标识单个区块的那句安静的话,属于同一类坦率——“链”是个方便的虚构,在链尖附近,高度是一种主张,而不是一个地址。然后是默克尔树,在这里本章既最好,也最自我批评:真正的魔法不是哈希,而是对数,那种使证明比区块小一万倍、从而使弱者的验证成为可能的压缩;而与之并列,难得的是,书引用了它自己源代码对重复 txid 缺陷的警告,一种并不伪造区块、而是毒害节点对区块的记忆的攻击,被打了补丁而不是被根治。后半部分转向测试网络,而本章在这里无意中证明了它最深的一点。Testnet3 运行同样的代码,手续费一文不值,随即行为失常,这表明比特币不是一种数据结构,而是一种激励结构。Signet 靠把区块授权交给两位点名的贡献者来修复这种混乱——一个在一本讲无需信任的书里被直白陈述的信任假设——并由此承认,无许可是你为价值付出的代价,而不是抽象中的美德;它自己的代价是,挖矿软件必须被流放回 testnet3,因为去除了混乱的沙盒,再也无法测试混乱的那一部分。Regtest 以一个 12462 比特币、一文不值的余额,和 4.6e-10 的难度,完成了图景,机制没变,只是把旋钮调低了,而且即使你一个人在房间里,100 个区块的币基成熟规则仍然咬人。读起来像是四条链的分类学的东西,其实是一种方法论——一架从 regtest 到 signet 再到主网的梯子,每一级都买到不同等级的真实感——而本章最后指向挖矿,指向使这一切结构变得昂贵到难以改写的东西。那是要带走的一句话:链接是免费的,锚定要花钱。把这一章读成一章穿着数据结构外衣的经济学,并留意它多少次在从句里对你说出了实话。
在 FeedLitra 里读第 11 章,每段旁边都有这些卡片。
开始读书第 12 章:挖矿与共识
工作量证明如何把电力变成链的选择?
第 12 章是怎样展开的AI 辅助
开篇:一次重新定义。 本章一开始,就把“挖矿”这个词从它自己的比喻里拿走。作者坚持说,挖矿首先不是关于产生币——而是去中心化的验证和清算,是由陌生人组成的网络,在没有权威来证明的情况下,就单一的交易历史达成一致的过程。新铸造的币是诱饵,而不是目的:区块奖励(减半的补贴加上交易手续费)的存在,是为了让每个矿工的自身利益,与保护网络的工作保持一致,而货币发行是支付这笔安全账单的副作用。这个框架一箭双雕。它设定了本章的解释议程——共识源于在每个节点上运行的四个独立过程,通过景的挖矿节点及其构造的币基交易戏剧化地展现——它也埋下了本章的长弧线,因为作者立刻指出,矿工的收入稳步地从补贴迁移到手续费:2009 年 1 月每个区块 50 个比特币,减半到 25,再到 12.5,到 2020 年 5 月是 6.25,在大约 2140 年降到零,约 2100 万枚币已被发行。关键在于,这 2100 万是个天花板,而不是配额;矿工可以少领规则允许的,但绝不能多领,这就是为什么那个直觉上的担忧——一个自己写工资单的矿工,不就可以写一个更大的吗——崩塌了。被夸大的付款,在其他所有人眼里会使整个区块无效,花在它的工作量证明上的电力也就白费了。
展开:机制,一块一块地组装。 从这个框架出发,本章下降到机制,而顺序就是构造的顺序。先是候选区块头及其字段——默克尔根、时间戳、nBits、nonce——然后是 SHA256 工作量证明和目标的概念。在这里,作者的演示刻意很谦逊:给“Hello, world!”后面附加数字并做哈希,直到结果以零开头,这需要尝试 32 次。这个玩具例子的要点是,哈希无法预测或操纵,所以挖矿是盲目的试错;然而一旦获胜的数字已知,任何人都能重新计算那一个哈希并立刻确认。正向不可猜测,反向微不足道——这种不对称,才使花费的工作可证明,而下游的一切都建立在它之上。本章随后加上自我调节的部分:每 2016 个区块重新调整一次,每个节点独立地按实际时间与预期时间之比重新缩放自己的目标,上限为四倍,所以巨大的失衡需要好几个周期才能消解;中位时间(Median Time Past);独立的区块验证;以及最大工作量链的选择。这些合起来解释了本章那条安静的结构性主张——区块顺序才是击败双花的东西。每条链为其交易固定一个序列,一次花费如果位于较早的区块里,就算较早,而较晚的交易只有在其输入尚未被消耗时才有效,所以两笔冲突的花费永远不会都成立。作者还停下来拆解了一个诱人的改革:更快的区块不会让支付更早结算。一个十分钟的区块和九个一分钟的区块,要求双花者付出同样十分钟的全网哈希工作量,所以它们同样安全,而更快的链还额外在竞争的分叉上浪费努力。更短的间隔并不买来最终性;它们只是让每次确认的意义变小。
转折:从机制到权力。 本章的支点,来自机制遇到了它自己的成功。不断上升的哈希率耗尽了 32 位的 nonce,迫使矿工去找额外的搜索空间——币基脚本的额外 nonce,以及后来的 BIP320 版本位。同样的升级,让单干挖矿成了一场彩票,推动了矿池的兴起:更容易的份额目标用来衡量贡献的工作,一边是受管理的矿池,另一边是 P2Pool 的份额链。在这里,作者纠正了第二个常见的误读。联合挖矿并不提高预期收益;它改变的是钱到来的方式。一个拥有全网 0.0001% 哈希率的矿工,独自大约二十年找到一个区块,但在一个持有 1% 的矿池里,每天能收到超过一个区块的份额分红——同样的期望,方差小得多,减去费用。但联合挖矿也集中了本章开篇称为分散的那种权力,而这就是转折。哈希率或“51%”攻击得到一个具体的演示:马洛里买了 25 万美元的画,卡罗尔在一次确认后就放行了,马洛里的同伙保罗用他的矿池,用一笔双花外加再往上的一个区块重新挖了那个区块,让卡罗尔既没了画,也没了付款。这个计划需要控制一个大矿池,矿池自己的自动化矿工也没注意到——而被可能的最简单的反制措施所击败:对高价值的销售,等待更多的确认。限度与威胁同样要紧:即使压倒性的哈希率,也无法改写已结算的历史,或偷走它并不持有的币。它只能扰乱最近的区块和攻击者自己的付款。真正的防御是确认的深度,而不是对矿工的信任。
收尾:究竟是谁在治理。 表明哈希率买到的控制权,比看上去的要少之后,本章提出了自然的后续问题——规则本身如何改变——并发现这也需要比挖矿算力更多的东西。硬分叉同时分裂四样东西:软件、网络、挖矿和链。它还分裂哈希率,同时让少数派的链困在旧的难度上,所以持有五分之一算力的链,大约每五十分钟产生一个区块,而且因为重新调整要等 2016 个区块,这种爬行持续大约十周,使容量下降大约五倍。软分叉通过保持向前兼容来避免分裂,只会收紧规则,并通过矿工信号来激活——先是 BIP34,然后 BIP9,然后 BIP8。结束这一序列的历史案例是 taproot:在 BIP9/BIP8 僵局之后,快速试验把它送过了关。从那段插曲,作者得出了本章的结论性论证,它回答了开篇的框架。即使挖矿算力的多数,也无法规定规则,因为权力分散在矿工、开发者、钱包、交易所、商家和用户之间。单独行动的矿工可以被直接无视——其他所有人都拒绝他们的区块,而他们只能在一条没有交易、没有商家、没有钱包、没有交易所的链上挖空区块,也就是一种没人看重的货币。这种扩散也是现状稳定的原因,也是任何改变都需要妥协的原因;95% 的软分叉门槛,是系统自己对需要多大的超级多数才能推动它的度量。于是本章结束在它开始的地方——挖矿是集体验证,而不是私人生产——但这一主张是通过机制挣得的,而不是被断言的。
关键论点,以及支撑它们的原文
挖矿首先是去中心化的验证和清算;它铸造的币是诱饵,不是重点。
作者把奖励——新铸造的币加上手续费——当作一种激励方案,让矿工的自身利益与保护网络保持一致,同时它也执行货币的发行,所以造钱是支付安全费用的副作用,而不是这番操作的目的。
“如果你只把挖矿看作创造比特币的过程,你就把手段(激励)误当成了这个过程的目标。”
“If you view mining only as the process by which bitcoins are created, you are mistaking the means (incentives) as the goal of the process.”
Mining and Consensus查看原文 →
基于这个奖励的框架,作者论证说,矿工的收入稳步地从新币迁移到交易手续费,直到 2140 年之后,只剩下手续费。
补贴在 2009 年 1 月从每个区块 50 个比特币开始,减半到 25,再到 12.5,到 2020 年 5 月是 6.25;它在大约 2140 年降到零,约 2100 万枚币已被发行。作者指出这个数字是个天花板,所以如果矿工少领了允许他们领的,实际发行量可以更低。
“2140 年之后,每个区块中的新比特币数量降为零,挖矿将只由交易手续费来激励。”
“After 2140, the amount of new bitcoins in each block drops to zero and mining will be incentivized only by transaction fees.”
Mining and Consensus查看原文 →
挖矿只能靠盲目的试错,因为没有人能预测或操纵哈希结果。
作者给“Hello, world!”后面附加数字,反复哈希;要尝试 32 次,才会出现以零开头的哈希。这个搜索纯粹是猜测,然而一旦获胜的数字已知,任何人都可以重新计算那一个哈希并立刻确认——这恰恰是花费的工作可证明的原因。
“哈希函数的结果无法预先确定,也无法创建一种能产生特定哈希值的模式。”
“The hash function’s result cannot be determined in advance, nor can a pattern be created that will produce a specific hash value.”
Mining and Consensus › Mining the Block查看原文 →
另外 3 个论点
更快的区块不会让支付更早结算——它们只会让每次单独的确认的意义变小。
针对更短的间隔意味着更快的最终性这种直觉,作者比较了一个十分钟的区块和九个一分钟的区块:无论哪种方式,双花者都得重做相当于全网十分钟哈希量的工作,所以两者同样安全,而更快的链还额外在竞争的分叉上消耗努力。
“区块之间更短的时间,并不带来更早的结算。”
“Shorter times between blocks doesn’t result in earlier settlement.”
Mining and Consensus › Assembling and Selecting Chains of Blocks查看原文 →
即使是哈希率攻击,也无法改写已结算的历史或偷走别人的币;它只能扰乱最近的区块和攻击者自己的付款,这就是为什么确认的深度才是真正的防御。
作者走过这样一个场景:马洛里买了 25 万美元的画,卡罗尔在一次确认后就把画交了出去,马洛里的同伙保罗用他的矿池,用一笔双花外加再多一个区块,重新挖了那个区块,让卡罗尔既没了画,也没了钱。这个计划需要控制一个大矿池,矿池自己的自动化矿工也没注意到,而对高价值的销售,只需等待更多的确认就能击败它。
“最佳区块链上已确认的交易,随着时间推移变得越来越不可改变。”
“Confirmed transactions on the best blockchain become more and more immutable as time passes.”
Mining and Consensus › Hashrate Attacks查看原文 →
在本章结尾,作者论证说,即使挖矿算力的多数,也无法规定规则,因为权力分散在矿工、开发者、钱包、交易所、商家和用户之间。
如果矿工单独行动,其他所有人可以直接拒绝他们的区块,矿工只能在一条没有交易、商家、钱包或交易所的链上挖空区块——一种没人看重的货币。权力的这种扩散,也是作者说现状稳定、任何改变都需要妥协的原因,95% 的软分叉门槛反映了需要多强的超级多数才能推动系统。
“如果他们单方面行动,其余的参与者可能拒绝接受他们的区块,把经济活动保持在少数派链上。”
“If they act unilaterally, the rest of the participants may refuse to accept their blocks, keeping the economic activity on a minority chain.”
Mining and Consensus › Consensus Software Development查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
区块顺序阻止双花
每条区块链为其交易固定一个单一的顺序:一次花费如果位于较早的区块里,就算较早。较晚的交易只有在它所花费的输出尚未被较早的交易花费时才有效,所以对同一枚币的两次冲突的花费,不可能都成立。
机制 2
为什么难度一直在浮动
哈希算力和矿工数量多年来剧烈波动,然而区块仍必须平均十分钟一个。所以每 2016 个区块,每个节点按上一段实际花费的时间与应当花费的时间之比,重新缩放它自己的目标,变化上限为四倍,这意味着巨大的失衡需要好几个周期才能自己消解。
机制 3
为什么少数派的链在爬行
硬分叉既分裂哈希率,也分裂软件,但幸存的少数派链继承了旧的难度。只有五分之一的算力,它的区块大约每五十分钟到来一个,而且因为重新调整要等 2016 个区块,这种爬行持续大约十周,使交易容量下降大约五倍。
常见误读
既然矿工写的是付给自己的交易,一个贪婪的矿工完全可以给自己发一个比规则允许的更大的奖励。
被夸大的付款,在其他所有人眼里会使整个区块无效,所以它被拒绝,花在它的工作量证明上的电力也白费了;补贴是一个矿工只能少领、绝不能超出的天花板。
“与普通交易不同,币基交易不消耗(花费)UTXO 作为输入。”
“Unlike regular transactions, the coinbase transaction does not consume (spend) UTXOs as inputs.”
Mining and Consensus › The Coinbase Transaction查看原文 →
加入矿池,会让小矿工比单干挖得更多。
预期收益基本相同;改变的是钱到来的方式。一个拥有全网 0.0001% 哈希率的矿工,独自大约二十年找到一个区块,但在一个持有 1% 的矿池里,平均每天能收到超过一个区块的份额分红——更稳定、不确定性小得多的收入,被矿池费用略微减少。
“唯一根本的区别,是他们收到分红的频率。”
“The only fundamental difference is the frequency of the payments they receive.”
Mining and Consensus › Mining Pools查看原文 →
第 12 章的核心概念
- 挖矿
- 节点验证交易、用工作量证明把它们打包进区块,从而保障共识的过程。
- 适用处: 主要不是印钱的过程;奖励是激励,不是目标。
- 涌现的复杂性
- 全网范围的一致,从许多独立的节点遵循简单规则中出现,没有投票,也没有固定的决定时刻。
- 适用处: 没有明确的选举;共识只是异步交互的产物。
- 区块补贴
- 矿工每个区块可以领取的新创造的比特币,每 210000 个区块减半,直到降为零。
- 适用处: 它是上限:矿工可以少领,从而降低总发行量。
- 币基交易
- 区块中的第一笔交易,支付矿工补贴加手续费,不花费任何 UTXO。
- 适用处: 被夸大的币基使整个区块无效,所以矿工不能给自己多付。
- 全节点验证
- 每个节点在中继之前,独立地对照一长串清单检查每笔交易,建立它的内存池。 每个节点用同一份标准清单检查每个新区块,所以违反规则的矿工会失去他们的奖励和电力。
- 适用处: 标准会随时间变化,以增加特性或阻止拒绝服务攻击。 验证能阻止作弊,却无法阻止一次由遵守规则的多数进行的重组。
- 工作量证明
- 因为哈希输出不可预测,低于目标的哈希证明了花费了已知的平均计算量。
- 适用处: 只是统计性地估计工作量;任何单次成功都可能是靠运气。
另外 13 个概念
- 难度调整
- 每 2016 个区块,每个节点按实际时间与期望时间之比重新缩放目标,使区块保持平均 10 分钟。 难度只在每 2016 个区块重新调整一次,所以失去哈希率的链,在那之前会遭受缓慢的区块。
- 适用处: 每个周期的变化上限为四倍,而且跨度用的是 2015 个区块。 分裂之后分别适用于每条分叉的链。
- 中位时间(MTP)
- 共识时间,取最近 11 个区块的中位时间戳,用于所有时间锁检查。
- 适用处: 比挂钟时间大约慢一个小时。
- 额外 nonce 的解决办法
- 把币基脚本(或版本位)中的空闲空间用作额外的 nonce 空间,让快速的矿工可以继续搜索区块头的变体。
- 适用处: 改变币基脚本会迫使重新计算默克尔根的左侧;时间戳只能稍微拉长,否则区块就无效了。
- 矿池
- 许多矿工在矿池协议下合并哈希算力并分配奖励,用较小的分红换来频繁、可预测的分红。
- 适用处: 降低了分红的方差,但不降低总的预期收益,而受管理的矿池会增加运营者的费用和信任。
- 份额目标
- 矿池设定的一个更容易的目标,使每个矿工频繁地证明可度量的工作,按努力成比例地赚取份额。
- 适用处: 份额在比特币网络上没有价值;只有低于网络目标的区块头才能赢得一个区块。
- 份额链
- P2Pool 的并行低难度链,在没有任何中央矿池服务器的情况下,记录每个矿工的份额奖励。
- 适用处: 本身容易受 51% 攻击,要求每个矿工有一个全节点,且已经不再使用。
- 多数攻击
- 持有多数哈希算力的矿工有意分叉链,来双花自己的交易,或审查某些地址。
- 适用处: 只影响未来的共识和攻击者自己的交易;密钥和签名保持安全,深处的历史实际上不可改变。
- 硬分叉
- 一次共识规则的改变,可能让网络永久分裂成两条各自演进的链。
- 适用处: 需要所有参与者之间的协调;不像暂时的自然分叉,它可能永远不再汇合。
- 硬分叉的阶段
- 硬分叉分四步增长:软件分叉、网络分叉、挖矿分叉、链分叉。
- 适用处: 仅有软件分叉还不够;还需要采用和激活。
- 软分叉
- 一种旧客户端仍然接受的规则改变,所以不发生链的分裂。
- 适用处: 只能收窄什么是有效的,绝不能放宽。
- 软分叉信号
- 矿工标记区块来表明已经准备好,一旦达到门槛,规则就激活。
- 适用处: BIP9 让矿工可以拖住一个提案;BIP8 增加了一个强制的信号期。
- 快速试验
- 一种修改过的 BIP9 激活,只给矿工一个很短的信号窗口,如果信号成功,约六个月后开始强制执行。
- 适用处: 用过一次,用于 taproot;将来的软分叉是否会再用它,不清楚。
- 权力的扩散
- 对比特币规则的权威,分散在矿工、协议和钱包开发者、交易所、商家和用户之间,所以没有谁能单独行动。
- 适用处: 矿工凭 51% 可以审查交易,但只能在其他群体同意的范围内。
第 12 章划线与批注AI 陪读
“你是把手段(激励)误当成了这个过程的目标”
“you are mistaking the means (incentives) as the goal of the process”
查看原文 →一个干净的修辞动作:作者在建造任何东西之前,先没收了读者直觉上的比喻。把“挖矿”称为误导,也是一次安静的坦白:中本聪的品牌打得太成功了。
“不可撤销的努力已被花费,用来保障他们收到的比特币的安全”
“irrevocable effort was expended securing the bitcoins they received”
查看原文 →注意这里用什么代替了信任:不是签名,不是权威,而是沉没成本。安全就是被变得可读的、浪费掉的能源。
“矿工可以有意挖出一个领取少于全额奖励的区块”
“a miner may intentionally mine a block taking less than the full reward”
查看原文 →2100 万的上限通常被当作经文引用;脚注揭示它是一个没人有义务去达到的天花板。被烧掉的补贴是意外的永久通缩。
另外 17 条批注
“许多经济学家论证说,通缩的经济是一场灾难”
“Many economists argue that a deflationary economy is a disaster”
查看原文 →本章短暂地从工程走进意识形态——而反驳被框定为“比特币专家们论证”,一个做了大量未经挣得的权威工作的标签。
“惩罚储蓄者,以救助债务人(包括最大的债务人,政府本身)”
“punishes savers in order to bail out debtors (including the biggest debtors, governments themselves)”
查看原文 →面具在这里完全掉下来了。这是一个政治论点,而不是协议的描述——而括号才是真正的论证。
“之所以是涌现的,是因为共识不是明确达成的——没有选举,也没有共识发生的固定时刻”
“Emergent because consensus is not achieved explicitly—there is no election or fixed moment when consensus occurs”
查看原文 →到目前为止最深的一句话。我们习惯性地把一致想象成一个决定性的事件;比特币把它消解为一种统计倾向。没有任何东西变成真的,它只是变得更昂贵而难以撤销。
“一个被夸大的奖励,会导致该区块被其他所有人判定为无效,白白浪费了景的电力”
“an inflated reward would result in the block being deemed invalid by everyone else, wasting Jing’s electricity”
查看原文 →优雅:矿工自己写自己的工资单,而这之所以安全,只因为其他每个人都在审计它。诚实不是被假定的——而是被弄得比欺诈更便宜。
“《泰晤士报》2009年1月3日,财政大臣濒临对银行实施第二轮救助”
“The Times 03/Jan/2009 Chancellor on brink of second bailout for banks”
查看原文 →一个动作,两项功能——时间戳和宣言。任意数据字段,是协议的政治被永久刻进它自己的第一个区块的地方。
“产生匹配某个特定目标的哈希结果的唯一办法,就是一次又一次地尝试”
“the only way to produce a hash result matching a specific target is to try again and again”
查看原文 →所有的宏伟都归结为野蛮的愚蠢。巧妙之处不在搜索,而在选择了一个无法被智胜的问题——不可跳过的劳动,是唯一没人能伪造的东西。
“输入本身就构成了证据,证明做了一定量的工作”
“the input itself constitutes proof that a certain amount of work was done”
查看原文 →优雅的转折:答案自带它的收据。不需要审计员,不需要信任——产物就是审计。
“导致重新调整偏向更高的难度 0.05%”
“resulting in a retargeting bias toward higher difficulty by 0.05”
查看原文 →一个 2009 年的 bug 被永远冻结进规则,因为修复它会分裂货币。共识把笔误变成了法律。
“比特币可以扩展并保持安全,而无需在今天的水平上增加任何哈希算力。”
“Bitcoin can scale up and remain secure without any increase in hashing power from today’s level.”
查看原文 →真,却滑头——安全确实与交易数量脱钩,但它紧紧挂钩于价格。作者在紧接着的下一段里悄悄丢掉了这一点。
“每个参与者对时间都有自己的视角”
“each participant has his or her own perspective of time”
查看原文 →本章最深的一行。一个分布式系统不可能有时钟,所以它用一个中位数制造了一个——时间变成了一次投票。
“为了去除撒谎的激励”
“To remove the incentive to lie”
查看原文 →注意这里承认了什么:矿工们对时间撒谎,是理性的。协议没有说教,只是去除了回报。
“答案是它们同样安全。”
“The answer is that they’re equally secure.”
查看原文 →反直觉的关键:确认是工作量的单位,不是时间的单位。不知道其背后的哈希率,六个区块毫无意义。
“它唯一的优势,是向愿意接受这些保证的人提供较弱的保证。”
“Its only advantage is providing weaker guarantees to people who are willing to accept those guarantees.”
查看原文 →美妙而带刺的一句话——它把一整类竞争链,重新框定为在兜售打扮成速度的不耐烦。
“他们找到一个区块来抵消其电力和硬件成本的可能性是如此之低,以至于这相当于一场赌博,就像玩彩票。”
“The likelihood of them finding a block to offset their electricity and hardware costs is so low that it represents a gamble, like playing the lottery.”
查看原文 →废除了可信第三方的系统,把它们重新生成为矿池。去中心化的数学,重新中心化的工资单。
“每个矿池矿工都被给予一个略有不同的币基交易模板”
“Each pool miner is given a slightly different coinbase transaction template”
查看原文 →巧妙:矿池不需要信任它的成员,因为每个份额都在暗中付给矿池。作弊将意味着给别人挖矿。
“这是为玩家衡量骰子点数的一种公平办法,而且它偶尔会产生一次小于四的点数”
“it was a fair way to measure dice throws for the players, and it occasionally produces a less-than-four throw”
查看原文 →整个矿池经济都建立在这上面:一个与获胜相关、却不是获胜的代理指标。份额是押在运气上的借据。
“免除他们运行全节点的负担”
“relieving them of the burden of running a full node”
查看原文 →被框定成一种好处,但这恰恰是中心化的机制——矿工外包验证,运营者才获得了两段之后所描述的权力。
读后感AI 陪读
第12章是《精通比特币》不再描述数据结构、而开始描述一种政治秩序的一章,它一开始就掏了读者的口袋。第一个动作是没收“挖矿”这个词:币是手段,不是目的——目的是去中心化的验证。这是个干净的修辞开场,也是一次安静的坦白:中本聪的品牌打得太成功了,所以在任何真实的东西能够建立于其上之前,这个比喻必须被强行拿掉。从这里起,本章按一条非常有意的弧线展开:激励,然后是候选区块及其区块头字段,然后是工作量证明和目标、重新调整和中位时间(Median Time Past)、独立验证和最大工作量链的选择,然后是矿池,然后是攻击,然后是分叉,然后是治理。作为一个整体来读,这条弧线是一个论证,而不是教学大纲。它从无需信任的最小单位——一个没人能抄近路的哈希——走向最大的单位,那是一场关于规则究竟是什么的、人与人之间的对峙。中间的一切,是让前者扩展成后者的机制。
我看得最清楚的,是本章在根基上的替换。这里没有任何东西靠签名、身份或权威来保障;它靠沉没成本来保障。“不可撤销的努力已被花费”,用六个字概括了整个安全模型。工作量证明并不聪明——文字直截了当地说,命中目标的唯一办法是一次又一次地猜——而这种愚蠢就是重点。巧妙之处在于选择了一项无法被智胜、被外包、被伪造的任务,使答案自带收据:产物就是审计,不需要审计员。同样的模式在每个层次重复。矿工自己写自己的工资单,而它之所以安全,只因为其他每个人都独立地检查它——诚实不是被假定的,而只是被弄得比欺诈更便宜。矿工们理性地对时间戳撒谎,所以协议没有说教;它去除了回报。一个分布式系统不可能有时钟,所以它用十一个区块的中位数制造了一个,时间本身变成了一次投票。而共识,本章最深的一行,是涌现的:没有选举,没有时刻,没有账簿条目是达成一致发生的地方。比特币里没有任何东西变成真的——它只是变得更昂贵而难以撤销。这一个重新框定,比任何表格都更好地解释了确认:六个区块是一个工作量,不是一个时间量,这就是为什么两条区块间隔大相径庭的链可以“同样安全”,也是为什么更快的链,如作者美妙的讥刺所说,是在兜售打扮成速度的不耐烦。
继续阅读
我最尖锐的判断是,本章恰恰在它最自信的地方最弱,而接缝在三个地方露了出来。第一,作为工程夹带进来的意识形态:关于通缩是不是灾难的离题,靠的是“比特币专家们论证”——一个做了大量未经挣得的权威工作的标签——而真正的论证在一个括号里,说储蓄者被惩罚以救助债务人,“包括政府本身”。那是一个政治论点,应当被当作一个来读,而不是当作协议的属性。第二,比特币可以在不增加哈希率的情况下扩展的主张,是真的,却很滑头:安全确实与交易数量脱钩,却与价格紧紧挂钩,文字把这一点丢进下一段,然后就走过去了。第三,也是后果最重的,矿池。废除了可信第三方的系统,把它们重新生成为矿池运营者——去中心化的数学,重新中心化的工资单。本章对机制是令人钦佩地诚实的:单干挖矿是一场彩票,份额是一个与获胜相关却不是获胜的代理指标,是押在运气上的借据;每个矿工得到一个不同的币基模板,所以矿池从不必信任任何人,因为作弊只会意味着给陌生人挖矿。但当它把矿池挖矿描述为“免除他们运行全节点的负担”时,它把中心化的确切机制框定成了一种便利——然后,两段之后,又描述了这种外包的验证所造成的运营者权力。这两段话应该在同一句话里,而本章把它们分开了。
后半部分挣得了它的位置,表明规则也只是和执行它们的人一样固定。0.05% 的重新调整偏差是完美的缩影:一个 2009 年的差一错误,永远冻结成了法律,因为改正它会分裂货币。共识把笔误变成了经文——同样的逻辑揭示 2100 万的上限,是一个没人有义务去达到的天花板,因为矿工可以少领,把差额烧成永久性的意外通缩。硬分叉同时分裂软件、网络、哈希率和链,难度落后于离开的哈希率;软分叉只收窄什么是有效的,因而保持向前兼容,这就是它们可以通过矿工信号溜进来的原因——也是为什么 BIP34、BIP9 和 BIP8 其实是对一个协议无法在内部回答的问题的、接连的回答尝试:谁来说“是”。Taproot 的快速试验,在 BIP9/BIP8 僵局之后到来,是诚实的结尾:不是技术突破,而是一次谈判达成的休战。于是本章的收尾主张落地了——权力分散在矿工、开发者、钱包、交易所、商家和用户之间,这使现状极其稳定,也使改变需要妥协。
我要对读者说的是:把这一章读两遍,一遍为机制,一遍为论证,因为它两者都在做,却只宣布其一。机制是美丽的,真正无需信任的——不可跳过的劳动,自我验证的答案,作为一种统计倾向而不是一个事件的一致。底下的论证是,这个机制产生一种特定的钱和一种特定的权力分配,而在第二个问题上,本章是参与者,不是叙述者。留意语域转变的那些时刻——“许多经济学家论证”、“免除他们的负担”、“保持安全而无需任何增加”——因为每一处都标志着一个有争议的主张穿着技术事实的制服。并且带走本章最好的教训,它根本不是关于哈希的:比特币的持久,与其说来自密码学,不如说来自改变任何东西(包括它的错误)的成本。这里的不可变性不是数学上的保证——而是每个人无法就一项改进达成一致所留下的、化石般的残余。
在 FeedLitra 里读第 12 章,每段旁边都有这些卡片。
开始读书第 13 章:比特币安全
使用复杂脚本时,恢复码究竟必须包含什么?
第 13 章是怎样展开的AI 辅助
开篇:现金的类比与利害。 本章不是从技术开始的,而是从重新框定开始。它坚持说,比特币不是银行余额;它更接近数字现金或黄金,而“占有就是法律的十分之十”。开篇列出价值可以直接消失的种种方式——丢失、放错地方、被偷、被误转——并指出在这些情形中,协议都不提供追索权。定下这个惨淡的框架之后,文字立刻给出了它的制衡:与现金或黄金不同,钱包是一个文件,所以可以被复制、被备份,甚至被打印出来。开篇因此确立了本章的支配性张力——比特币在某些方面比以前的东西更严酷,在另一些方面则更宽容——并得出结论,它“足够不同”,需要以一种新颖的方式来思考安全。
展开:从原则到架构。 本章的中段从抽象向下推进到设计。首先是安全原则,立足于去中心化:因为安全建立在独立验证而不是把关之上,网络可以是开放的,不需要加密。这一点通过与信用卡的持续对比被加锐,信用卡的支付工具是一个开放式的私有标识符,可以被反复用来“拉取”资金,迫使采用端到端加密,并在被攻破时让客户面临身份盗窃。相比之下,一笔比特币交易授权的是一个特定价值给特定接收者,不透露任何私密信息,也不能授权进一步的付款——因此有了那个惊人的主张:交易可以安全地在不安全的 WiFi 或蓝牙上广播。这笔取舍被诚实地点了出来:这个模型杜绝了大规模失陷,却把负担转到用户身上,他们于是“被黑,一个接一个”。论证随后转向开发者,带着一条直截了当的规则——不要从用户手里拿走密钥,也不要外包验证——以及早期交易所把所有资金汇集在单一服务器上单一热钱包里的警示案例,它复制了比特币本想逃离的那个脆弱的中心化模型。信任之根一节,完成了概念的弧线,它取一个熟悉的安全思想(从一个最小的、最不复杂的核心向外辐射的同心信任层),并把它的中心挪了位置:在比特币里,信任之根是创世区块和一条完全验证的区块链,别无其他。随附的方法是实用的——假设每个组件都被完全攻破,然后问应用是否仍能成立——而被黑的交易所作为证明重新出现,它们曾把信任寄托在热钱包、中心化数据库和弱密钥上。
转折:从系统到人,从失窃到丢失。 本章随后转换语域。前半部分论证的是架构,“用户安全最佳实践”论证的是人的脆弱:物理安全有几千年的历史,数字安全不到五十年,而通用操作系统——运行着来自几百位作者的数千个组件——并不适合存钱。比特币把利害抬高了,因为被偷的币不需要销赃或洗白;它们本身就有价值。但文字拒绝以警报收场,指出这种激励恰恰推动了硬件加密、签名设备、多重签名方案和托管方面的真实创新。从这里起,实际建议随之而来,而第二个、更安静的转折也随之到来:最大的风险不是失窃,而是丢失。实体存储和冷存储被提供,作为把一个陌生的问题转成熟悉问题的办法;硬件签名设备被呈现为靠功能有限而不是增加复杂性来获得的安全。然后“确保你的访问”用 2011 年的案例,反转了本章自己的重点:大约 7000 个比特币的丢失,不是败给攻击者,而是败给了精心设计的加密备份,其密钥被放错了地方——把币保护得太好,你可能再也找不到它们了。一条警告延伸了这一点:使用多重签名或复杂脚本时,仅有密钥和种子可能不够,因为花费条件也必须是可恢复的。
收尾:把风险分散到人和时间上。 最后的乐章把风险沿几条轴线分散。跨应用,通过分散投资——只放不超过一小部分,也许 5%,作为“零花钱”,其余分散在桌面和冷存储里。跨人,通过多重签名和治理,密钥独立生成,由不同的高管持有,这样没有任何一个人能危及资金,同时也提供冗余。以及跨时间,通过生存能力——持有者死亡或丧失行为能力时的可用性这一被忽视的要求,在这种情形下,对谁也不分享的标准建议,可能让一个家庭无法恢复他们甚至不知道存在的资金;提供的补救办法是一位可信的亲戚或律师,或通过一位“数字资产执行人”做多重签名的遗产规划。本章以适度的谦逊结束:比特币仍是一项仍在探索中的复杂技术,更好的工具将会到来,而在此期间,这些做法就是用户所拥有的。
关键论点,以及支撑它们的原文
比特币支付可以在完全开放的信道上传输,无需加密。
作者对比了两种支付模型:信用卡扣款带着用户的私有标识符,并且是开放式的,所以网络在传输和存放时都必须受到保护,而一次失陷会让客户面临身份盗窃。比特币交易不透露身份,无法伪造,也不能授权额外的付款,所以在不安全的 WiFi 或蓝牙上广播它,在安全上没有任何损失。
“事实上,你可以在开放的公共信道上广播比特币交易,比如不安全的 WiFi 或蓝牙,而不损失任何安全性。”
“In fact, you can broadcast Bitcoin transactions over an open public channel, such as unsecured WiFi or Bluetooth, with no loss of security.”
Bitcoin Security › Security Principles查看原文 →
去中心化的安全消除了大规模失陷的风险,却把保守密钥秘密的负担转移到了个别用户身上。
顺着前一点,作者指出,因为安全建立在独立验证而不是把关之上,就不存在可以被大规模洗劫的、集中的凭据存储。反面是,密钥放在联网的手机和笔记本上,上面运行着来自几百位作者的数千个程序,一个流氓组件就能读取键盘和文件,所以用户是一次一个地被黑,而不是成批地被黑。
“事实上,你可以在开放的公共信道上广播比特币交易,比如不安全的 WiFi 或蓝牙,而不损失任何安全性。”
“In fact, you can broadcast Bitcoin transactions over an open public channel, such as unsecured WiFi or Bluetooth, with no loss of security.”
Bitcoin Security › Security Principles查看原文 →
开发者不得夺走用户对密钥的控制权,也不得外包交易验证。
作者指出早期的交易所把所有客户的资金汇集进一个热钱包,密钥放在单一服务器上;许多被黑,给客户造成了毁灭性的后果。他允许一个狭窄的例外——在运营安全、分层访问控制和银行那样的审计上大量投入——但指出即便如此,这个设计也只是重新创造了传统的金融模型,带着它的身份盗窃和挪用公款。
“简单说:不要把密钥的控制权从用户手里拿走,也不要外包验证。”
“In simple terms: don’t take control of keys away from users and don’t outsource validation.”
Bitcoin Security › Developing Bitcoin Systems Securely查看原文 →
另外 3 个论点
应用唯一应当明确信任的,是一条完全验证的区块链。
作者提供了一个从信任之根的想法推出的具体检验:依次取每个组件,假设它完全在恶意行为者的控制之下,然后问系统是否仍能成立。被黑的交易所在随便一看之下就没通过这个检验,因为它们把信任寄托在热钱包、中心化数据库和弱加密密钥上,而不是链上。
“评估你应用安全架构的一个好办法,是考虑每一个单独的组件,并评估一个假想场景:该组件被完全攻破,落入恶意行为者的控制之下。”
“A good method to evaluate the security architecture of your application is to consider each individual component and evaluate a hypothetical scenario where that component is completely compromised and under the control of a malicious actor.”
Bitcoin Security › The Root of Trust查看原文 →
因为比特币本身就承载价值,它们加剧了偷窃的激励,进而加剧了改善安全的激励。
作者观察到,偷信用卡号和账户令牌的窃贼,以前必须销赃和洗白被盗的数据,然而盗窃仍在升级;币不需要这样的转换,这使它们成为格外有吸引力的目标。他论证说,同样的风险清晰度也驱动着防御者,并举出了此前三年里涌现的硬件加密、离线密钥存储和签名设备、多重签名方案,以及数字托管。
“就像把钱埋在沙漠里藏起来一样,如果你把比特币保护得太好,你可能再也找不到它们了。”
“Like hiding money by burying it in the desert, if you secure your bitcoins too well you might not be able to find them again.”
Bitcoin Security › Ensuring Your Access查看原文 →
丢失访问与被抢劫同样要紧,所以持有应当分散开来,并使之能够幸存。
2011 年 7 月,一个教育项目因为放错了其精心设计的备份的加密密钥,丢失了近 7000 个比特币——安全紧得连所有者自己也进不去。因此作者建议,在线钱包或手机钱包里放也许不到 5% 作为零花钱,其余分散在桌面和冷存储里(这是经验法则,不是算出来的数字),外加与一位可信的亲戚或律师共享访问权,这样丧失行为能力或死亡不会让资金搁浅。
“就像把钱埋在沙漠里藏起来一样,如果你把比特币保护得太好,你可能再也找不到它们了。”
“Like hiding money by burying it in the desert, if you secure your bitcoins too well you might not be able to find them again.”
Bitcoin Security › Ensuring Your Access查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
为什么支付流量不需要保密
信用卡号是一个可重复使用的标识符,所以任何截获它的人都可以一次又一次地拉取资金,迫使整个网络必须端到端加密。比特币交易则是把一个金额锁定给一个接收者,无法伪造,也不赋予授权进一步付款的权力,所以复制它的窃听者什么也得不到。
机制 2
信任属于最简单的核心
软件越复杂,包含的 bug 就越多,所以传统的设计把信任锚定在最小的、最难攻破的核心上,并在它外面包裹更复杂的层。比特币对应的核心是一条验证回溯到创世区块的链;应用所信任的任何其他东西,都增加了一个可能独立出故障的组件。
机制 3
过度保护如何摧毁访问
加到备份上的每一层保护,都引入一个必须自己幸存下来的新秘密。给备份加密,使币取决于加密密钥而不是钱包,所以丢掉那一把密钥,每一份副本都成了无用的数据,资金变得无法触及,协议没有补救。
常见误读
如果比特币流量不需要加密,而且它的设计抵抗大规模失陷,那么普通用户的币默认就相当安全。
协议的开放只意味着被截获的交易对攻击者无用;一切仍然取决于在你自己的设备上保守花费密钥的秘密。作者强调,通用操作系统并不适合持有数字货币,而让一台机器没有病毒和木马,超出了大多数用户的技能,这就是为什么个别用户一再被攻破。
“事实上,你可以在开放的公共信道上广播比特币交易,比如不安全的 WiFi 或蓝牙,而不损失任何安全性。”
“In fact, you can broadcast Bitcoin transactions over an open public channel, such as unsecured WiFi or Bluetooth, with no loss of security.”
Bitcoin Security › Security Principles查看原文 →
备份私钥,或它们所来自的 BIP32 种子,就足以在以后把币找回来。
大多数输出脚本承诺于花费这些币必须满足的条件,而钱包必须能够向网络出示这些条件。因此恢复数据也必须包括脚本的细节,这对多重签名和其他复杂的安排尤其要紧,它们增加了治理和冗余,代价是更重的备份要求。
“拥有花费某些比特币的密钥,等同于拥有现金或一块贵金属。”
“Possession of the keys to spend certain bitcoins is equivalent to possession of cash or a chunk of precious metal.”
Bitcoin Security查看原文 →
第 13 章的核心概念
- 信任之根
- 安全系统由此向外构建的、最不复杂、最受信任的核心;在比特币里,它是通往创世区块的、经过验证的链。
- 适用处: 只有当应用确实自己验证链时才适用;信任任何其他组件,都会重新引入脆弱性。
- 冷存储
- 让密钥在从未联网的机器上生成并保存,放在纸上或离线介质里。
- 适用处: 能防远程失窃,却提高了备份或加密密钥放错地方时永久丢失的风险。
- 密钥即所有权
- 持有花费密钥就是所有权的全部;丢失或泄露它们,协议没有补救。
- 适用处: 花费还可能需要备份脚本和条件,而不只是密钥或种子。
- 脚本式多重签名
- 要求在资金能够移动之前,由不同的人、在不同的地方持有的几个签名。
- 适用处: 增加冗余和治理,却增加了恢复的复杂性和备份的要求。
另外 0 个概念
第 13 章划线与批注AI 陪读
“嗯,在比特币里,占有就是法律的十分之十。”
“Well, in Bitcoin, possession is ten-tenths of the law.”
查看原文 →一句可爱的话,悄悄承认这个系统没有上诉法院。措辞的魅力,软化了实际上是一个残酷的设计选择。
“你可以在开放的公共信道上广播比特币交易,比如不安全的 WiFi 或蓝牙,而不损失任何安全性”
“you can broadcast Bitcoin transactions over an open public channel, such as unsecured WiFi or Bluetooth, with no loss of security”
查看原文 →对交易的内容来说是真的,对用户却不是。开放广播会泄露时间、IP 和地址关联——隐私损失不等于安全损失,而这句话把它们混为一谈了。
“许多用户没有能力充分保护他们的密钥,于是被黑,一个接一个”
“many users are not able to adequately secure their keys and get hacked, one by one”
查看原文 →本章里最诚实的一句话。去中心化并不废除大规模的损失,它只是把它零售化。把一个个损失加起来,你得到的是一次和任何银行一样大的失陷,只是没有人可以起诉。
另外 5 条批注
“归根结底,唯一应当被明确信任的,是一条经过完全验证的区块链。”
“Ultimately, the only thing that should be explicitly trusted is a fully validated blockchain.”
查看原文 →优雅,却仍然不够。你还信任你的硬件、你的随机数生成器、你的编译器,以及做验证的代码。信任之根被挪动了,而不是被消除了。
“比特币也创造了改善计算机安全的激励。”
“Bitcoin also creates the incentives to improve computer security.”
查看原文 →在承认用户被一个个挑出来之后,乐观的转折来得可疑地快。攻击者立刻变现;防御者则按委员会的节奏改进。激励的对称是被假定的,而不是被证明的。
“2011 年 7 月,一个著名的比特币宣传和教育项目丢失了近 7000 个比特币。”
“In July 2011, a well-known Bitcoin awareness and education project lost almost 7,000 bitcoin.”
查看原文 →这里最好的轶事,因为敌人是所有者自己的勤勉。每一层安全,也是一层可能失败而锁死的东西——而加密密钥也是密钥,需要它自己的备份,永远往下套。
“在过去三年里,作为比特币被采用的直接结果”
“Over the past three years, as a direct result of Bitcoin adoption”
查看原文 →第三版里一个相对的时间标记——三年,从什么时候起算?文字围绕这句话被修订过,却没有修订这句话本身。
“你应该考虑与一位可信的亲戚或律师共享访问细节”
“you should consider sharing access details with a trusted relative or lawyer”
查看原文 →在一整章坚持不该有人持有你的密钥之后,生存能力又把你送回信任一个人。本章最难的问题,得到的是一段话和一个职称。
读后感AI 陪读
本章真正的论证是,比特币把安全从机构转移到了个人,而它真正的弱点是,它把这叙述为净收益,而它自己的例子却说明并非如此。安东诺普洛斯在描述种类上的差异时最尖锐:信用卡号是对你的可重复使用的索取权,所以线路必须加密;比特币交易是一次性的授权,所以线路不需要加密。这种不对称真的很有启发,而信任之根的重新框定——洋葱层被一条通往创世区块的、经过验证的链所取代——连同“逐个组件假设被攻破”的思想实验,是本章最好的思想动作,后者是一种可用的审计方法,而不只是口号。但本章总是在一个问题只是被挪动了的时候,就宣布它被解决了。信任没有被消除,只是被推到了硬件、随机数生成器和验证代码里。大规模的失陷没有被阻止,而是被零售给了一个个用户,文字承认了这一点,然后匆匆带过,并用一个关于改善激励的乐观主张敷衍。最能说明问题的是,结尾的两节论证反对本章自己的前提:2011 年的损失表明,防御本身就是隐患,因为每一层加密,都是多一样可能丢失的东西,而生存能力一节最后建议你把访问权交给亲戚或律师——一个人为的信任之根,在几页警告的反对之后,用一段话又重新引入了。关于需要备份脚本和条件、而不仅仅是密钥的警告框,是这里悄悄地最实用的东西,值得的不只是一个侧栏。本章所缺少的,是对它所暗示之事的任何清算:一个其安全模型要求每个用户成为自己的银行、运行在作者本人称为不太安全的硬件上的系统,并没有消除脆弱性——而是分散了它,并且没有给输家留任何追索权。这笔交易也许仍值得做。只是本章从未承认它是一笔交易。
在 FeedLitra 里读第 13 章,每段旁边都有这些卡片。
开始读书第 14 章:第二层应用
通道究竟是如何惩罚发布过时的承诺交易的?
第 14 章是怎样展开的AI 辅助
开篇:比特币作为平台。 本章一开始,把框架从比特币作为货币,转向比特币作为应用的基底。它列举了系统所提供的长期保证——一致性、原子性、完整性等等——然后做出核心主张:这些是可组合的原语:没有任何一个保证单独产生一个应用,但把几个叠起来就能。众筹的例子承载着这个论证。因为对一个输入签名,就把它绑定到一个固定的输出,捐款可以累积在一个池里,直到目标达成之前都不可花费;这种行为是由一致性、原子性和完整性共同作用而来的,其中任何一个单独都不行。这确立了本章的方法:先引入一个原语,然后表明在它之上能建造什么。
展开:有色币,以及移到链下。 以这种方式建造的第一个应用是有色币——通过一次性封印、支付到合约的承诺和客户端验证,在比特币之上发行的资产,成熟为 RGB 和 Taproot Assets。这里惊人的结果是,碰到链的东西少得可怜。一把支付到合约调整过的密钥,与普通公钥无法区分,所以鲍勃可以把他一半的有色币分配给一个 UTXO,而在任何看着链的人面前都没有可见的关联,监视按构造就被击败了。代价是对称的:所有权靠交给接收者密钥、合约条款和先前的历史,在链下证明,所以接收者在那段历史上依赖发送者,而不是从区块链上读取。比特币的全节点从不评估合约,资产状态也没有全局共识——这一点值得牢牢记住,因为它与“在比特币上”就意味着“被比特币验证”的直觉恰好相反。较早的方案,比如 EPOBC,更粗糙,标记一个 1 聪的输出;现代设计则把一切都隐藏起来。
转折:打破朴素的通道,然后修复它。 本章随后引入支付通道和状态通道——注资、承诺和结算交易——而在这里,它的节奏变得真正辩证。刚刚展示了链下更新有多便宜之后,作者立刻打破了朴素的版本。在艾玛/法比安按秒付费看视频的例子里,一个普通的 2-of-2 通道失败了两次:艾玛可以广播承诺 #1,只为她实际看过的 600 秒中的一秒付费,而如果对手方干脆消失,注资输出就完全没有逃生路径。修复依次到来,每一个修复前一个残留的缺陷。带时间锁的退款,解决了资金冻结的问题。递减的绝对时间锁——斯皮尔曼通道——解决了重放作弊,因为承诺 #600 在 #1 甚至还没有效之前 600 个区块就变得可花费,所以最新的状态总是赢得竞赛。但这个修复限制了通道的寿命:一个锁定 4320 个区块的 30 天通道,最多容许 4320 个状态,并把退款搁置得那么远。
通道问题的解决:撤销加 CSV。 最终的构造是不对称的可撤销承诺。每一方都持有一份不同的承诺,它立即付给对手方,却把自己的付款锁在一个相对时间锁(CSV)之后。这个延迟就是执行的窗口:一旦受害者持有撤销密钥的两半,他们就可以扫走全部余额,所以发布一个被撤销的状态,输的比赢的多。是经济学,而不是计时器,让通道保持诚实——这就是为什么它现在可以无限期保持开放,闪电网络的 48 位状态索引允许超过 281 万亿次更新。本章明确指出的警告是,这种执行是手动的、有时限的:必须有人注意到被撤销的状态,并在相对时间锁窗口(作者的例子里是 1000 个区块)关闭之前花掉惩罚分支。“自动惩罚”会是一个误读;勤勉地盯着链是一项真正的要求。
收尾:把各跳链成网络。 有了一个安全的两两通道,本章把它向外延伸。HTLC 把支付锁定在跨一连串通道的同一个哈希上,所以爱丽丝可以通过鲍勃、卡罗尔和戴安娜付钱给埃里克——五个参与者,两两之间有 4 比特币的通道——而无需开设任何新的链上通道,也无需任何一跳信任另一跳。这个机制是两个缩小的量:每一跳转发的钱比收到的稍微少一点(差额就是它的手续费),并设定一个比所得到的更短的退款截止时间(这个差距保证它在向下游付款之后仍能向上游索取)。如果某一跳无法领取,整条链就回到之前的余额;唯一残留的暴露,是一次延迟的退款。Sphinx 洋葱路由然后把路径包裹在嵌套的加密里,用固定大小、填充过的数据包,连路径的长度也隐藏,所以每一跳转发的是它读不懂的内层消息。本章退后一步,点明这买到了什么:毫秒级的结算,按数量级提高、受节点吞吐量而不是区块空间限制的容量,精细的支付粒度,以及发送者的隐私——这一切都无需信任,而且没有哪一项是比特币特有的,因为这个设计只需要一条支持多重签名、时间锁和基本合约的基础链。
关键论点,以及支撑它们的原文
比特币之所以能作为平台,是因为应用来自把它的几个保证叠在一起,而不是来自其中任何单独一个。
作者的众筹例子结合了一致性、原子性和完整性:因为对一个输入签名就把它绑定到一个固定的输出,捐款可以堆积起来,而在达到筹款目标之前仍不可花费——没有任何单独的保证能产生这种行为。
“比特币提供的构件,是一个信任平台的要素,可以用来组合出应用。”
“The building blocks offered by Bitcoin are elements of a trust platform that can be used to compose applications.”
Second-Layer Applications › Applications from Building Blocks查看原文 →
如今的有色币设计,把资产数据完全留在链外,只发布看起来完全普通的密钥。
一把支付到合约调整过的密钥,与任何其他公钥无法区分,所以鲍勃可以把他一半的有色币分配给一个 UTXO,而与爱丽丝所看到的交易没有可见的关联,从而击败链上监视;所有权是靠把密钥、合约条款和先前的历史在链下交给新的接收者来证明的,这也意味着那个接收者在这段历史上依赖发送者,而不是从链上读取。较早的方案,比如 EPOBC,更粗糙,标记一个 1 聪的输出。
“P2C 调整过的密钥有一个强大的特性:除了爱丽丝和鲍勃,对其他所有人来说,它们看起来都和任何其他公钥一样,除非他们选择公开用来调整密钥的合约。”
“A powerful attribute of P2C tweaked keys is that they look like any other public keys to everyone besides Alice and Bob, unless they choose to reveal the contract used to tweak the keys.”
Second-Layer Applications › Pay to Contract (P2C)查看原文 →
展示了链下通道有多便宜之后,作者立刻打破了朴素的版本:一个普通的 2-of-2 通道可能永远冻结资金,并让付款人重放一个过时的、更有利的状态。
在按秒付费看视频的例子里,艾玛的余额在 600 份承诺中逐步变化,直到最后一份给法比安 6 毫比特,并返还给她 30——但没有什么能阻止她广播承诺 #1,只为她实际看过的 600 秒中的一秒付费;对称地,如果对手方消失,注资输出就没有逃生路径。
“通道失败了,因为艾玛可以通过广播一个对她有利的先前承诺来作弊。”
“The channel fails because Emma can cheat by broadcasting a prior commitment that is in her favor.”
Second-Layer Applications › Making Trustless Channels查看原文 →
另外 3 个论点
让每一份后续承诺的绝对时间锁更短,确实能阻止重放作弊,但它限制了通道的寿命和更新次数——这恰恰是撤销密钥和相对时间锁取代它的原因。
承诺 #600 在 #1 甚至还没有效之前 600 个区块就变得可花费,所以最新的状态总是赢得竞赛,而双花预防使其余的退役;代价是一个锁定 4320 个区块的 30 天通道,最多容许 4320 个中间状态,并把退款搁置得那么远——终点越远,被困的一方等得越久。相比之下,撤销密钥加 CSV 的构造,让通道可以无限期保持开放,闪电网络用 48 位索引给状态编号,每个通道有超过 281 万亿次更新,前提是有人真的盯着链来执行惩罚。
“每一份后续的承诺交易,都必须有更短的时间锁,这样它才能先于它的前任、先于退款交易被广播。”
“Each subsequent commitment transaction must have a shorter timelock so that it may be broadcast before its predecessors and before the refund transaction.”
Second-Layer Applications › Making Trustless Channels查看原文 →
把哈希锁合约链接到同一个哈希上,让一笔支付能穿过完全陌生的人,而没有哪一跳信任另一跳。
五个参与者,两两之间有 4 比特币的通道,通过鲍勃、卡罗尔和戴安娜,把 1 个比特币从爱丽丝转给埃里克,而无需开设任何新的链上通道;每个中间人因短暂地承诺资金而赚取手续费,而如果下游某一跳无法领取其合约,整条链就直接回到之前的余额,所以没有人亏钱。唯一残留的暴露,是路径失败或通道关闭时一次延迟的退款。
“为了他们在通道中资金的短期承诺,他们可以赚取一小笔手续费,唯一的风险是,如果通道被关闭或路由支付失败,退款会有一点延迟。”
“For the short-term commitment of their funds in the channel they are able to earn a small fee, with the only risk being a small delay in refund if the channel was closed or the routed payment failed.”
Second-Layer Applications › Basic Lightning Network Example查看原文 →
本章最后把闪电网络呈现为一种通用的第二层路由技术,它提升比特币的容量、速度、支付粒度和隐私,同时保持运作无需信任。
支付在几毫秒内结算,系统容量按数量级上升,只受节点容量和速度而不是区块空间的限制;在隐私方面,发送者把路径包裹在嵌套的加密里,所以每一跳可以把内层消息转发给下一个节点而不读它,而用随机数据填充的固定大小数据包,连路径有多长也隐藏了。这个设计并非比特币特有——它只需要一条支持多重签名、时间锁和基本合约的基础链。
“LN 是一种第二层的路由技术。它可以应用于任何支持某些基本能力的区块链,比如多重签名交易、时间锁和基本的智能合约。”
“An LN is a second-layer routing technology. It can be applied to any blockchain that supports some basic capabilities, such as multisignature transactions, timelocks, and basic smart contracts.”
Second-Layer Applications › Lightning Network Benefits查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
有效的承诺保持不发布
每一次通道更新都是一笔完全有效的、花费注资输出的交易,但双方只是持有它而不广播。由于只有最后一个状态才会被结算,这一对可以每秒修改余额几十次,而链只看到注资和结算交易。
机制 2
靠撤销密钥加 CSV 延迟来惩罚
每一方持有一份不同的承诺,它立即付给对手方,却把自己的付款锁在相对时间锁之后。这个延迟是一个窗口,受害者一旦持有撤销密钥的两半,就可以在其中扫走全部余额,所以发布一个被撤销的状态,输的比赢的多——而通道也不需要到期日。
机制 3
沿着路径缩小的金额与超时
每一跳转发的钱比收到的稍微少一点,并设定一个比所得到的更短的退款截止时间。手续费的差额付给该跳,而超时的间隔保证它在向下游付款之后,仍有时间用揭示出来的秘密向上游索取,所以没有哪一跳需要信任它的邻居。
常见误读
有色币资产记录在比特币区块链上,所以比特币节点会验证谁拥有它们。
这些资产对比特币来说是外在的:只有一把调整过的公钥到达链上,而全节点从不评估它背后的合约。每个接收者只验证它即将接受的币的历史,而这必须从发送者那里获得——资产状态没有全局共识。
“有色币指的是一组类似的技术,用比特币交易来记录比特币之外的外在资产的创建、所有权和转移。”
“Colored coins refers to a set of similar technologies that use Bitcoin transactions to record the creation, ownership, and transfer of extrinsic assets other than bitcoin.”
Second-Layer Applications › Colored Coins查看原文 →
一旦有了撤销密钥的惩罚,作弊者会被自动惩罚,所以我可以开一个通道,然后不再关注。
执行是手动的、有时限的:诚实的一方必须注意到链上被撤销的状态,并在相对时间锁窗口(作者的例子里是 1000 个区块)到期之前花掉惩罚分支,这就是为什么这个构造被描述为需要勤勉地盯着链。
“现在,希特什和艾琳不再创建一笔双方都签名的单一承诺交易,而是创建两笔不同的、不对称的承诺交易。”
“Now, instead of creating a single commitment transaction that both parties sign, Hitesh and Irene create two different commitment transactions that are asymmetric.”
Second-Layer Applications › Asymmetric Revocable Commitments查看原文 →
第 14 章的核心概念
- 第二层应用
- 建在比特币之上、使用它的保证而不改变它规则的系统。
- 适用处: 它们依赖比特币来结算和锚定,但它们自己的规则并不由全节点执行。
- 有色币
- 用比特币交易来记录非比特币资产的创建、所有权和转移。
- 适用处: 这些资产是外在的:不存储在区块链上,所以比特币本身从不验证它们。
- 一次性封印
- 一种只能与其他数据绑定一次的数据结构;在比特币里,UTXO 扮演这个角色。
- 适用处: 只在一条有效链内不可能发生双花的地方才管用。
- 支付到合约(P2C)
- 调整接收者的公钥,使其承诺于一份约定的合约,之后可以揭示出来作为证明。
- 适用处: 合约从不由全节点验证;只有调整后的密钥到达链上。
- 客户端验证
- 每个接收者只检查与他们即将接受的币相关的资产历史。
- 适用处: 资产状态没有全局共识;验证的负担和隐私都留在本地。
- 支付通道
- 双方在链下交换有效但未发布的交易,只在最后才在区块链上结算。
- 适用处: 支付通道是状态通道的特例,其中被改变的状态是一个余额。
另外 8 个概念
- 支付通道承诺交易
- 一笔链下的、部分签名的交易,花费注资输出,记录通道当前的余额划分。
- 适用处: 在合作的情形下从不广播;只有最新的一份才应当到达链上。
- 不对称可撤销承诺
- 每一方持有一份不同的承诺,它立即付给另一方,却延迟自己的付款,所以作弊是可惩罚的。
- 适用处: 要求诚实的一方真的在延迟窗口内盯着链。
- 撤销密钥
- 一把由两半组成的秘密密钥;一旦你持有两半,如果另一方发布了被撤销的状态,你就可以夺走通道的全部余额。
- 适用处: 惩罚不是自动的;只有在 1000 个区块的延迟到期之前行使才管用。
- 相对时间锁(OP_CSV)
- 一个脚本层面的延迟,使承诺持有者自己的输出,只有在设定数量的区块之后才可花费。
- 适用处: 与撤销密钥结合,去掉了绝对时间锁所强加的通道寿命上限。
- 哈希时间锁合约(HTLC)
- 一份合约,付给揭示哈希原像的人,否则带时间锁地退款给付款人。
- 适用处: 用于双向和路由的通道,简单的单向通道不需要。
- 路由式支付通道(闪电网络)
- 由两方支付通道首尾相连组成的网络,使任何人都能通过跳过无需信任的中间人来付钱给任何人。
- 适用处: 需要一条支持多重签名、时间锁和基本智能合约的基础链;路由取决于通道容量和流动性。
- 洋葱路由的支付路径(Sphinx)
- 发送者把路径包裹在嵌套的加密层里,所以每一跳只知道前一个和后一个节点。
- 适用处: 只因为数据包是固定大小、用随机数据填充,才隐藏路径长度;最终的接收者仍然看到没有下一跳。
- 递减的 HTLC 金额与超时
- 每一跳转发的钱略少,退款超时更短,付给该跳一笔手续费,并保证它在向下游付款之后能向上游索取。
- 适用处: 安全取决于每一跳的超时间隔;如果秘密从未出现,余额只是回到原样。
第 14 章划线与批注AI 陪读
“不可变性由能源来担保”
“Immutability is underwritten by energy”
查看原文 →五个字说完整个信任模型——不是法律,不是机构,而是热力学。也悄悄承认这个保证是经济性的,而不是绝对的。
“一笔有效的交易不会过期。”
“A valid transaction does not expire.”
查看原文 →奇怪的时间性质:一个签名的意图无限期地漂浮着,等待。这恰恰是支付通道把它们整个架构挂上去的钩子。
“在一张 1 美元的钞票上盖章,写上“这是 ACME 的一张股票凭证”
“stamping a $1 note with a message saying, "this is a stock certificate of ACME”
查看原文 →这个类比诚实得过了头——它暴露出比特币什么也没携带;所有的意义都存在于同意兑现那个印章的人那里。
另外 17 条批注
“关于合约,没有任何东西被公开揭示——甚至他们之间存在一份合约这件事也没有。”
“Nothing is publicly revealed about the contract—not even that a contract between them exists.”
查看原文 →优雅的反转:链著名的透明性,恰恰由于被用来什么也不说,而成了隐私的基底。
“因为全节点不会(也不能)验证合约是否被正确遵循”
“Because full nodes don’t (and can’t) validate that the contract is followed correctly”
查看原文 →这是第二层真正的代价,直白地说了出来。验证并没有消失,只是被挪到了接收者身上。
“那段历史很像我们称为区块链的常规比特币交易的历史,但有色的历史是完全不可见的”
“That history is a lot like the history of regular Bitcoin transactions that we call the blockchain, but the colored history is completely invisible”
查看原文 →一条嵌套在公共链内部的私有区块链,被锚定却不可读。美丽,又隐隐令人眩晕。
“免费的美式看涨期权”
“the _free American call option”
查看原文 →一个衍生品定价的攻击,浮现在一个路由协议内部——你一旦让接收者可以延迟接受,你就免费给他们写了一份期权。
“其实,“通道”这个词是个比喻。”
“Actually, the term channel is a metaphor.”
查看原文 →作者停下来说出这一点,很好。许多区块链的困惑,来自读者把比喻的家具当真。
“我们还将从一个朴素的假设开始:没有人试图作弊”
“We will also start with the naive assumption that no one is trying to cheat”
查看原文 →教学上的暗示——简单的版本是一个将被撤回的谎言。一切有趣的东西都活在修复之中。
“支付通道”的概念和术语,对用户都是完全隐藏的。”
“Both the concept and the term "payment channel" are completely hidden from the users.”
查看原文 →第二层安静的论点:成功意味着消失。艾玛只是在看视频。
“如果她可以发送承诺交易 #1,只为 1 秒钟的视频付费,为什么要为 600 秒的视频付费?”
“Why pay for 600 seconds of video if she can transmit commitment transaction #1 and only pay for 1 second of video?”
查看原文 →作者一直用第一人称来叙述激励——这是表明这里的安全是经济性的、而不是密码学的最干净的办法。
“终点越远,退款就越远。”
“The more distant the endpoint, the more distant the refund.”
查看原文 →一句话承载了整个设计缺陷。通道寿命和人质时间是同一个数字——你无法调一个而不惩罚另一个。
“只有法比安同时拥有一份承诺交易的两个签名,所以只有他能广播其中的一份承诺”
“only Fabian has both signatures for a commitment transaction, so only he can broadcast one of those commitments”
查看原文 →优雅的不对称:把广播的权力交给其贪婪本就指向正确方向的一方。只因为钱朝一个方向流动才管用。
“尽管它们只有用于见证(隔离见证)交易时才是安全的,而后者直到 2017 年才可用”
“although they are only safe to use with witness (segwit) transactions, which didn’t become available until 2017”
查看原文 →一个聪明的构造与它变得安全之间,隔了四年。值得留意比特币的第二层想法有多少次在等基础层的修复——这里是延展性。
“其中一方可能很小气,拒绝合作,迫使另一方做单方面关闭”
“one of the parties can be petty, refuse to cooperate, and force the other party to do a unilateral close”
查看原文 →注意设计的美德:恶意对怀有恶意的人也变得昂贵。对称的痛苦,是可得的最便宜的威慑。
“取消一笔交易的唯一办法,是让一笔冲突的交易得到确认。”
“The only way to cancel a transaction is to get a conflicting transaction confirmed.”
查看原文 →本章的一切都从这一个不可移动的约束中生长出来。撤销密钥并不取消任何东西——只是让使用它变成自杀。
“如果希特什作弊,艾琳将得到两个输出。”
“If Hitesh cheats, Irene gets BOTH outputs”
查看原文 →大写字母是作者在喊出笑点。延迟不是惩罚——而是惩罚得以实施的窗口。
“重要的是,撤销不会自动发生。”
“Importantly, the revocation doesn’t happen automatically.”
查看原文 →这是没人宣传的隐藏代价:闪电网络的安全要求在线并盯着。无需信任是真实的,但它按注意力给你开账单。
“如果卡罗尔无法领取他的 HTLC,而他也无法领取爱丽丝的 HTLC,一切都会回到之前的通道余额,没有人受损。”
“If Carol is unable to claim his HTLC and he is unable to claim Alice’s HTLC, everything reverts back to the prior channel balances and no one is at a loss.”
查看原文 →递减的超时,才使这一点成立——每一跳的退款窗口,都在它所依赖的窗口之后关闭。很容易忽略这个顺序有多承重。
“支付路径上的中间各方,都不必彼此信任。”
“None of the intermediate parties in the payment route had to trust each other.”
查看原文 →对失窃是真的,对隐私和路途中被锁住的资金则含糊其辞。“无需信任”在这句话里做了很重的活。
读后感AI 陪读
第14章是比特币不再是账簿、而成了基底的一章,它的形状是一个论证被执行了两次。它一开始,把基础层的保证盘点成仿佛是库函数——由能源而不是法律担保的不可变性,授权而不会过期的签名,绑定条件的脚本,给时间盖戳的链——然后表明,应用与其说是比特币的扩展,不如说是这几个原语的重新组合。这个框架是本章真正的论点,而两半部分是它的两个证明。资产层(有色币、RGB、Taproot Assets)只用链做一件事:一次性封印,一种对其所承诺的内容只字不提的、不可重复的承诺。支付通道用链做另一件事:一个没有人打算前往的终审法院。两半都建立在同一个不可移动的约束之上,几乎是顺带陈述的——取消一笔交易的唯一办法,是让一笔冲突的交易被确认——而本章几乎一切聪明之处,都是对这句话的变通,而不是对它的逃离。
我把它当作一个整体来读所看穿的是,第二层不是从区块链得到更多的办法,而是一笔交易,在其中,验证和活性被从链上移到了参与者身上。客户端验证是它诚实的名字:全节点不会、也不能检查有色币合约是否被遵循,所以接收者必须自己走一遍私有的历史。这种优雅是真实的——一条嵌套在公共链内部的平行链,由它锚定,却又对它不可读,在那里,链著名的透明性,恰恰由于被用来什么也不说,而成了隐私的基底。但“盖了‘ACME’章的 1 美元钞票”的类比,是本章最诚实的时刻,因为它承认比特币什么也没携带。意义完全存在于同意兑现那个印章的人那里,再多的密码学也提供不了那种同意。
继续阅读
通道的一半是更好的教学,而且是有意如此。它从一个朴素的、信任的构造开始,然后分阶段撤回信任的假设,这样每一次修复都可以读作对某一次具体攻击的回答:带时间锁的退款,用来逃离被劫持为人质;递减的承诺,使艾玛为第二秒而不是那一小时付费;斯皮尔曼的单向不对称,把广播的权力交给其贪婪本就指向正确方向的一方;然后,一旦钱必须双向流动,就是带 CSV 延迟和撤销密钥的对称可撤销承诺。读这个序列,反复出现的工具不是密码学的,而是经济学的:这里的安全,意味着让有利可图的一步成为诚实的一步,并让恶意对怀有恶意的人代价高昂。撤销并不取消旧的承诺——什么也做不到——它只是让发布一份变成自杀,而 CSV 延迟不是惩罚,而是惩罚得以实施的窗口。HTLC 随后把同样的动作推广到陌生人之间:带递减超时的链式哈希锁,其中这些到期的顺序是承重的部分,因为每一跳的退款窗口必须在它所依赖的窗口之后关闭。Sphinx 洋葱路由隐藏路径,而本章以收益结束——隐私、速度、粒度、容量。
我最尖锐的判断是,本章对它自己的代价令人钦佩地坦率,却把它们作为旁白归档,而不是作为结论。有三条值得提升。第一,撤销不是自动的:只有当你或一位代理人在线并盯着,你的资金才是安全的,所以无需信任是真实的,但它按持续的注意力给你开账单——一种基础层从未施加的活性要求。第二,“没有人需要信任任何人”对失窃是真的,对其他一切就弱得多;中间跳会知道金额和时间,而你的钱可能在路途中被锁住,同时一场停滞上演。免费的美式看涨期权是这一点的尖锐形式:一旦接收者可以延迟接受,你就无偿地给他们写了一份衍生品,而那是一个出现在路由协议内部的定价问题。第三,斯皮尔曼方案里的时间张力——通道寿命和人质持续时间,字面上就是同一个数字——清楚地说明,这些构造并没有消除取舍,而是把它们挪进了某个人必须选择的参数里。
我要对读者说的是:别把这一章读成产品目录。把它读成一个演示:基础层是有意极简的,每个第二层设计都是对“我们最少能要求链做什么?”的回答。读的时候牢记两个习惯。把比喻当作脚手架——作者停下来说“通道是个比喻”,而许多区块链的困惑,来自读者把比喻的家具当真——没有任何东西在流动,双方只是持有相互签名、尚未广播的状态。每当一个构造许诺不劳而获,就问问现在是谁在做验证,谁必须保持在线,以及在他们等待时,谁的资本被锁住。还要留意本章安静的历史课:带不对称可撤销承诺,只有在 2017 年隔离见证修复了延展性之后才是安全的,那是在这个想法出现多年之后。第二层不是漂浮在第一层之外的;它要等着第一层。最后,注意本章几乎羞怯地陈述的、衡量成功的真正标准——概念和术语对用户完全隐藏。艾玛只是在看视频。当这种工程管用时,没人能看出它在那里,这既是它的胜利,也是它的代价如此容易被人不再计算的原因。
在 FeedLitra 里读第 14 章,每段旁边都有这些卡片。
开始读书附录 A:中本聪的比特币白皮书
匿名公钥的隐私模型,在多输入关联面前能站得住吗?
附录 A是怎样展开的AI 辅助
开篇:被框定为信任之成本的问题。 附录一开始,是一条确立出处的编者注——这是 2008 年 10 月的论文,原样转载——然后是论文自己的摘要,它把整个论证压缩成一段话:直接的点对点支付,作为局部解决办法的数字签名,以及原本要由一个可信第三方来填补的双花缺口。引言随后放慢,论证的是动机而不是机制。它的抱怨是经济性的,而不是密码学的:因为金融中介必须调解争端,交易永远不可能真正不可逆,而这种可逆性向外扩散成交易成本、最小可行的支付规模、商家对顾客的怀疑,以及被接受的欺诈基线。实体现金当面避免了这一切;通过线路,没有任何东西能避免。这一节以点出所需要的东西结束——一个基于密码学证明而不是信任的系统——并陈述了论文将不断回到的安全条件:诚实节点必须共同控制比任何合作的攻击者团体更多的 CPU 算力。
展开:一层一层地建造这台机器。 论文的中段是建设性的,每一节都恰好提供前一节所缺少的部分。“交易”把一枚币定义为一条数字签名的链,并立刻承认了缺陷——收款人可以验证所有权,却无法验证较早的花费的不存在。显而易见的修复,一个中央造币厂,被否决了,因为它重新创造了银行。由此引出一项苛刻的要求:要确认不存在,你必须知道所有的交易,所以交易必须被公开宣布,参与者必须就单一的顺序达成一致。“时间戳服务器”通过对一批条目做哈希并发布该哈希来提供顺序,每个时间戳都包含前一个,使链自我强化。“工作量证明”然后用 Hashcash 式的扫描,寻找带有前导零位的哈希,取代了报纸的发布——这种工作产生起来指数级昂贵,验证起来微不足道,而且是复合的,因为改动一个旧区块,意味着重做此后的每个区块。这一节的第二个动作在概念上是决定性的:工作量证明也回答了谁来投票。一个 IP 一票是可伪造的;一个 CPU 一票则不然,而最长的链就是多数的决定。关于通过移动平均调整难度的简短一段,在硬件改进时让区块的产生保持稳定。“网络”把整个协议简化为六个步骤,并处理了实际的混乱——由哪个分支下一个变长来打破平局,以及对丢失的广播的容忍。
转折:从机制到动机。 “激励”是论文从工程转向经济学的地方,也是论证的铰链。区块的第一笔交易为其创建者铸造一枚新币,这同时奖励了参与,并在没有发行者的情况下分配了货币供应——明确类比于采金,CPU 时间和电力是所花费的资源。交易手续费补充它,并将在达到预定的币供应量之后最终取代它,使系统不会通胀。收尾的主张把安全本身重新框定为一个激励问题:拥有多数算力的攻击者,必须在偷回自己的付款,和直接赚币之间做选择,而既然规则对他的有利程度超过所有其他人加起来,诚实就是更有利可图的选项——攻击会损害他自己财富的有效性。
巩固:扩展、验证与隐私。 三个较短的章节然后回应怀疑的读者会提出的反对意见。“回收磁盘空间”和“简化支付验证”论证系统是实用的:80 字节的区块头,一年不过几兆字节,而轻客户端可以只用区块头加一条默克尔分支来验证一笔支付,信任网络接受了该交易,而不是直接检查它。论文对这一取舍是坦率的——这种方法可能被一个压倒网络的攻击者欺骗,所以经常收款的企业仍应运行全节点。“价值的合并与拆分”解释了多个输入和输出、典型的一笔付款加找零的形状,并把扇出打发为不成问题。“隐私”然后承认,强制性的公开宣布摧毁了银行式的机密性,并把隐私挪到了别处:保持公钥匿名,每笔交易用一对新的密钥,并接受多输入交易仍然会泄露共同所有权——论文直白地陈述了这个残余风险,而不是把它糊弄过去。
收尾:量化许诺,然后重述它。 “计算”把早先的含糊一笔带过——“概率呈指数递减”——变成了算术。它首先界定了损害:即使更快的攻击者,也无法凭空创造价值或夺取别人的币,只能逆转自己最近的花费。竞赛被建模为一个二项随机游走,然后建模为对攻击者隐藏进度的泊松分布,重新整理以避免无穷的尾巴,并呈现为一个简短的 C 函数。数值表是回报:在 q=0.1 时,六次确认就已把成功率压到 0.03% 以下,而最后一张表给出了在每种攻击者份额下,亚 0.1% 风险所需的确认深度——从 10% 时的 z=5,到 45% 时的 z=340,在那里,随着 q 接近 p,指数保证明显崩塌。结论然后回到开篇的主题,现在是挣得的:无需信任的电子交易,用签名建造所有权,用工作量证明建造顺序,恰恰因为其无结构的简单性而稳健——节点不被识别,消息是尽力而为的,参与者可以离开再重新加入,并用 CPU 算力投票,办法是延伸有效的区块,并拒绝在无效的区块上工作。附录结束在论文正文之外,是一份许可说明,解释白皮书带有该软件的 MIT 许可,随后是许可文本本身——它在这里可以被重印的正式依据。
关键论点,以及支撑它们的原文
只要交易仍然可逆,经由金融机构路由的在线支付所带来的成本,就无法靠工程消除。
因为机构必须调解争端,商家向顾客索要额外的信息,一部分欺诈被作为不可避免的而注销,调解成本给交易规模设了一个下限,扼杀了小额随意的支付。现金在当面避免了这一切,但作者指出,通过通信信道的支付,不存在对等的东西。
“居中调解的成本增加了交易成本,限制了实际可行的最小交易规模,也断绝了小额随意交易的可能,而且还有一个更广泛的代价:失去了为不可逆的服务做不可逆支付的能力。”
“The cost of mediation increases transaction costs, limiting the minimum practical transaction size and cutting off the possibility for small casual transactions, and there is a broader cost in the loss of ability to make non-reversible payments for nonreversible services.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Introduction查看原文 →
在摆出这个问题之后,作者论证说,中央造币厂不可能是答案,因为确认一枚币没有被花过的唯一办法,是每个人都看到每一笔交易。
一串签名可以证明所有权,却无法表明过去的所有者没有更早地把这枚币也签给了别人。一个重新发行每枚币的造币厂可以发现这一点,然而它使整个货币系统取决于一家处理每笔支付的公司——就像银行一样。因此交易必须被公开宣布,参与者必须就到达的单一顺序达成一致。
“居中调解的成本增加了交易成本,限制了实际可行的最小交易规模,也断绝了小额随意交易的可能,而且还有一个更广泛的代价:失去了为不可逆的服务做不可逆支付的能力。”
“The cost of mediation increases transaction costs, limiting the minimum practical transaction size and cutting off the possibility for small casual transactions, and there is a broader cost in the loss of ability to make non-reversible payments for nonreversible services.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Introduction查看原文 →
工作量证明把多数决定变成了花费成本的问题,而不是清点身份的问题,而最长的链就是那个多数的裁决。
按一个 IP 地址一票来算,会让任何能分配许多地址的人接管,而哈希算力无法廉价地变出来——所以背后工作量最多的链,代表最多的计算能力。作者补充了条件:这只有在诚实节点控制那些算力的多数时才成立,因为难度会重新调整到稳定的区块速率,不管是谁在挖矿。
“工作量证明本质上是一个 CPU 一票。”
“Proof-of-work is essentially one-CPU-one-vote.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Proof-of-Work查看原文 →
另外 3 个论点
一个有足够硬件来攻击的贪婪参与者,诚实地挖矿比欺诈别人更划算。
他面临的选择,是逆转自己的付款,还是用同样的算力去赚取新币。规则给最大的矿工的新币,比所有其他人加起来还多,而一次攻击会损害他已持有的财富的有效性——所以自利的算术,倾向于按规则行事。
“这种激励可能有助于鼓励节点保持诚实。”
“The incentive may help encourage nodes to stay honest.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Incentive查看原文 →
普通用户无需存储或验证整条链,就能检查自己是否收到了钱。
只保留最长链的区块头,加上把一笔交易连到它所在区块的默克尔分支,就表明网络节点接受了这笔支付,此后每个区块都增加确认。作者直白地陈述了局限:这信任的是多数,所以一个持续的、压倒网络的攻击者,可以给这样的用户喂伪造的交易,这就是为什么经常收款的企业仍应运行全节点。
“根据我们 p > q 的假设,随着攻击者必须追赶的区块数增加,概率呈指数下降。”
“Given our assumption that p > q, the probability drops exponentially as the number of blocks the attacker has to catch up with increases.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Calculations查看原文 →
顺着对多数的这种依赖,作者表明,比诚实网络弱的攻击者,改写一笔付款的机会,随着其上每个区块而呈指数地缩小。
把竞赛建模为随机游走,把攻击者隐藏的进度建模为泊松分布,公布的数字表明,当攻击者持有 10% 的算力时,追上的概率从一个区块之后的约 0.20,降到十个区块之后的约 0.000001。这个结果假定诚实的区块花了平均的预期时间,并且诚实的算力超过攻击者的。
“根据我们 p > q 的假设,随着攻击者必须追赶的区块数增加,概率呈指数下降。”
“Given our assumption that p > q, the probability drops exponentially as the number of blocks the attacker has to catch up with increases.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Calculations查看原文 →
它是怎样运作的
本章论证所依靠的 3 个机制。
机制 1
为什么叠起来的工作量锁住了历史
矿工不断递增 nonce,直到区块哈希以足够多的零位开头——找起来昂贵,检查起来微不足道。此后每个区块都链接在那个哈希上,所以改动一个旧区块,意味着重做它的工作量和此后的每个区块,然后还要在竞赛中超过仍在延伸真实链的诚实节点。
机制 2
分叉如何自己解决
当两个区块同时出现时,每个节点在它先看到的那个上面构建,但保留对手的分支。无论哪个分支得到下一个工作量证明,就会变得更长,而落败一方的节点会切换过去——于是一致从最长链规则中涌现,而无需任何协调或消息路由。
机制 3
从新币到手续费
每个区块的第一笔交易,为找到它的人铸造币,这既补偿了花费的电力,又在没有发行者的情况下分发了货币。一笔交易的输入与输出之间的任何差额,都会被加作手续费,所以一旦发行结束,同样的奖励可以完全由手续费来资助,没有通胀。
常见误读
谁聚集了比网络其余部分更多的计算能力,谁就能随意改写账簿——凭空铸币,或夺取别人的余额。
即使一条成功的替代链,也只让攻击者撤销他自己最近的一笔付款。节点自己检查交易,并拒绝无效的交易,而诚实的节点不会在包含它们的区块上构建,所以一笔被偷的或凭空发明的付款,无论背后有多少工作量,都会直接通不过验证。
“根据我们 p > q 的假设,随着攻击者必须追赶的区块数增加,概率呈指数下降。”
“Given our assumption that p > q, the probability drops exponentially as the number of blocks the attacker has to catch up with increases.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Calculations查看原文 →
既然追上的概率呈指数下降,固定的少量确认对任何支付都是安全的。
你需要的深度,取决于攻击者所占的哈希算力份额。作者自己的表格,针对千分之一的失败率,对 10% 的攻击者要求 5 个区块,对 30% 要求 24 个,对 45% 要求 340 个——而整个计算假定诚实的算力仍超过攻击者的,且区块以预期的平均节奏到来。
“根据我们 p > q 的假设,随着攻击者必须追赶的区块数增加,概率呈指数下降。”
“Given our assumption that p > q, the probability drops exponentially as the number of blocks the attacker has to catch up with increases.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Calculations查看原文 →
附录 A的核心概念
- 工作量证明
- 搜索一个 nonce,使区块的哈希以足够多的零位开头;找起来难,检查起来便宜,重做起来昂贵。
- 适用处: 只有在诚实节点持有哈希算力多数时,它才保障顺序。
- 去中心化的信任网络
- 一组无结构的节点,通过延伸最长的工作量证明链,而不是靠身份或路由,来就历史达成一致。
- 适用处: 消息只是尽力而为;它保证最终一致,而不是即时投递。
- 币基交易
- 区块的第一笔交易,为矿工创造新币,在没有任何中央发行者的情况下启动了发行。
- 适用处: 新发行是有限的;此后激励完全转向交易手续费。
- 确认
- 叠在你的交易之后的区块;每多一个区块,少数派攻击者改写它的可能性就呈指数地降低。
- 适用处: 随着攻击者的份额 q 接近一半,所需的深度急剧上升。
另外 0 个概念
附录 A划线与批注AI 陪读
“他将不得不在两者之间选择:用它去欺诈别人,偷回自己的付款,还是用它来生成新币”
“he would have to choose between using it to defraud people by stealing back his payments, or using it to generate new coins”
查看原文 →整个安全模型最终不是靠数学,而是靠一个关于贪婪是理性的假设。一个有非财务动机的攻击者——一个国家,一个破坏者——会完全打破这一段。
“工作量证明本质上是一个 CPU 一票”
“Proof-of-work is essentially one-CPU-one-vote”
查看原文 →老得最糟糕的主张。ASIC 和矿池把一个 CPU 一票变成了一美元一票;抗女巫攻击的特性守住了,而这里隐含的平等主义没有。
“截至 2008 年,计算机系统通常出售时带 2GB 的内存”
“With computer systems typically selling with 2GB of RAM as of 2008”
查看原文 →有趣的是,论文里最过时的一句,是关于硬件的,而不是关于密码学。还要注意这个障眼法:他只估算了区块头的大小,悄悄把实际增长到数百 GB 的完整链放在一边。
另外 4 条批注
“隐私仍然可以通过在另一个地方切断信息流来维持:保持公钥匿名”
“privacy can still be maintained by breaking the flow of information in another place: by keeping public keys anonymous”
查看原文 →化名被当作隐私来兜售。他在两句话之后承认了关联的风险,而这个承认,原来成了整个链分析行业。
“一旦预定数量的币进入流通,激励可以完全过渡到交易手续费”
“Once a predetermined number of coins have entered circulation, the incentive can transition entirely to transaction fees”
查看原文 →一句话处理了系统里最难的悬而未决的问题——仅靠手续费能否资助安全。“能”在做大量未经检验的活。
“确认一笔交易不存在的唯一办法,是知道所有的交易。”
“The only way to confirm the absence of a transaction is to be aware of all transactions.”
查看原文 →整篇论文的支点。证明一个否定,需要完全的可见性——这恰恰就是为什么一种为隐私而造的货币,必须把每一笔支付都公开。
“它们不需要被识别,因为消息不会被路由到任何特定的地方”
“They do not need to be identified, since messages are not routed to any particular place”
查看原文 →无许可被重述为路由的属性。政治主张被当作工程上的便利夹带进来——而这恰恰是它奏效的原因。
读后感AI 陪读
九页,除了一个泊松求和之外没有任何方程,语气平淡得像一份协议备忘录——这正是这篇论文的修辞绝招:把一场货币革命呈现为对一个双花 bug 的修复。重读时最让我印象深刻的,是已被证明的和被假定的之间的不对称。反对链重组的概率论证无懈可击,甚至交付得过了头(一个 C 函数,三张表)。除此之外一切承重的东西——攻击者追求利润最大化,一个 CPU 大致相当于一个人,手续费最终可以取代补贴,匿名公钥等于隐私——每个只有一句话,没有任何辩护。比特币真实的历史,大体上是这些没有辩护的句子被压力测试的故事:挖矿集中到了工业资本手里,链分析消解了隐私的主张,而只靠手续费的终局仍未解决。最深的张力在“交易”一节,在那里中本聪承认,确认某事的不存在,需要知道所有的交易——这个动作买来了共识,又立刻抵押了隐私,而“隐私”一节只能偿还一部分的债。这篇论文持久的力量,不在于它预见了一切,而在于它让信任假设变得明确而局部:51% 的诚实哈希算力,直白地陈述,取代了一个你只能相信的机构。
在 FeedLitra 里读附录 A,每段旁边都有这些卡片。
开始读书论证在哪里吃力
不是反驳,而是细心的读者会想追问的地方。
- 轻量客户端被认可对许多用途够用,而同一个论证又坚持只有完整验证才让信任变得不必要,留下较弱客户端的可接受边界悬而未决。
“对许多实际用途来说,连接良好的轻量客户端已足够安全,在资源需求、实用性和安全性之间取得了平衡。但要想万无一失的安全,没有什么比运行全节点更好了。”
“For many practical purposes, well-connected lightweight clients are secure enough, striking a balance between resource needs, practicality, and security. For infallible security, however, nothing beats running a full node.”
The Bitcoin Network › Lightweight Clients查看原文 → - 削减区块传播延迟能保护小矿工,但最有效的进一步削减需要可信的私有中继,所以对中心化压力的补救,又在别处重新引入了信任。
“寻找区块的竞赛让最大的矿工占优势,所以它们的作用与比特币根本的去中心化背道而驰。”
“Block-finding races give the advantage to the largest miners, so they act in opposition to Bitcoin’s essential decentralization.”
The Bitcoin Network › Compact Block Relay查看原文 → - 去中心化被宣称为核心特性,然而由中本聪最初的作品发展而来的同一套代码库,仍是其他实现被期望匹配的参照。
“然后我们将检查来自你节点的区块、交易和其他数据,这些数据是权威的——不是因为某个强大的实体指定它们为权威,而是因为你的节点独立地验证了它们。”
“We’ll then inspect blocks, transactions, and other data from your node, data which is authoritative—not because some powerful entity designated it as such but because your node independently verified it.”
Bitcoin Core: The Reference Implementation查看原文 → - 密钥被说成是所有权的全部,然而表达所有权的地址会泄露它:重复使用把支付关联起来,一个被识别的地址也暴露了更早的历史。
“这些字段允许在验证签名与公钥相符之外(或代替它)执行额外的操作。”
“These fields allow additional operations to be performed in addition to (or instead of) verifying that a signature corresponds to a public key.”
Keys and Addresses › Output and Input Scripts查看原文 →
另外 4 处张力,以及 8 条证据上的局限
- 安全建议把用户推向离线的、多重签名的、分布式的保管,但增加的复杂性本身就是永久丢失的一个有据可查的原因,而只靠种子的恢复是不完整的,因为标签和路径是非确定性的。
“就像把钱埋在沙漠里藏起来一样,如果你把比特币保护得太好,你可能再也找不到它们了。”
“Like hiding money by burying it in the desert, if you secure your bitcoins too well you might not be able to find them again.”
Bitcoin Security › Ensuring Your Access查看原文 → - 挖矿被辩护为验证而不是发行,然而补贴计划趋向于零衰减,使这种验证的激励,取决于一个在通缩上限下未经检验的手续费市场。
“2140 年之后,每个区块中的新比特币数量降为零,挖矿将只由交易手续费来激励。”
“After 2140, the amount of new bitcoins in each block drops to zero and mining will be incentivized only by transaction fees.”
Mining and Consensus查看原文 → - 安全的经济一环是较弱的一环:它假定攻击者看重的是以他想要抹黑的系统计价的币,而基于成本的投票只有在算力保持分散时才能抵抗伪造身份,而设计中没有任何东西保证这一点。
“这种激励可能有助于鼓励节点保持诚实。”
“The incentive may help encourage nodes to stay honest.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Incentive查看原文 → - 第二层声称拥有基础层的保证而不改变规则,但通道的安全取决于各方保持在线以惩罚过时状态,也取决于可能被钉住(pinning)所挫败的手续费追加,所以链下的安全依赖于基础层不提供的警觉性。
“在通道的整个生命周期里,只需要把两笔交易提交到区块链上去挖:注资交易和结算交易。”
“In the entire lifetime of the channel, only two transactions need to be submitted for mining on the blockchain: the funding and settlement transactions.”
Second-Layer Applications › State Channels—Basic Concepts and Terminology查看原文 →
证据上的局限
- 许多核心论证是推理和叙事性的例证——爱丽丝的土地登记簿、穆罕默德的多重签名、单个挖矿节点——而不是对真实网络的度量。
“相比之下,比特币既不以实体形式存在,也不作为数字数据存在——爱丽丝不能把一些比特币递给鲍勃,或通过电子邮件发送出去。”
“By comparison, bitcoins don’t exist either physically or as digital data—Alice can’t hand Bob some bitcoins or send them by email.”
Transactions查看原文 → - 确认安全性的数字假定诚实的区块花了平均的预期时间,而所需的等待随攻击者份额急剧增长,所以这个保证只对明显处于少数的对手成立。
“根据我们 p > q 的假设,随着攻击者必须追赶的区块数增加,概率呈指数下降。”
“Given our assumption that p > q, the probability drops exponentially as the number of blocks the attacker has to catch up with increases.”
The Bitcoin Whitepaper by Satoshi Nakamoto › Calculations查看原文 → - 关键的定量主张是有时效性的策略默认值,而不是共识规则:546 聪的粉尘阈值、被变化的需求所作废的手续费估算,以及依赖于撰写时大约 50000 个中继节点的带宽算术。
“因为比特币的去中心化取决于许多人愿意运行全节点,包括比特币核心在内的若干全节点实现,通过影响未确认交易的中继与挖矿的策略,不鼓励创建不经济的输出。”
“Because Bitcoin’s decentralization depends on many people being willing to run full nodes, several full node implementations such as Bitcoin Core discourage the creation of uneconomical outputs using policies that affect the relay and mining of unconfirmed transactions.”
Transactions › Amount查看原文 → - 紧凑区块 97–99% 的节省,只有在对等节点正确猜到彼此的内存池内容时才成立,所以只要内存池出现分歧,标题数字就会下降。
“前面每一种方法的取舍是,它们在中心化下运作良好,但在去中心化的网络里不行,在那里单个节点不能信任其他节点。”
“The trade-off for each of the preceding methods is that they work well with centralization but not in a decentralized network where individual nodes can’t trust other nodes.”
The Bitcoin Network › Private Block Relay Networks查看原文 → - 总发行量被给定为约 2100 万比特币,但实际供应量可能更低,只要矿工领取的少于全额奖励。
“2140 年之后,每个区块中的新比特币数量降为零,挖矿将只由交易手续费来激励。”
“After 2140, the amount of new bitcoins in each block drops to zero and mining will be incentivized only by transaction fees.”
Mining and Consensus查看原文 → - 反对托管式和中心化设计的理由,主要建立在早期的交易所被黑事件和一次 2011 年备份密钥丢失之上,那是少数历史事件,而不是系统性的证据。
“简单说:不要把密钥的控制权从用户手里拿走,也不要外包验证。”
“In simple terms: don’t take control of keys away from users and don’t outsource validation.”
Bitcoin Security › Developing Bitcoin Systems Securely查看原文 → - 有几处技术例证明确是非规范性的,比如用 shell 实现的带计数器的哈希草图,代替实际的 BIP32 推导算法。
“使用确定性密钥生成的用户,只需记录他们的种子和所用确定性算法的引用,就可以备份钱包里的每一把密钥。”
“A user of deterministic key generation can back up every key in their wallet by simply recording their seed and a reference to the deterministic algorithm they used.”
Wallet Recovery › Deterministic Key Generation查看原文 → - 第二层机制只通过小型的双方场景来展示,而证明大小的优势是从一个示例区块算出来的,所以在规模上、在路由的多跳网络中、或在对抗条件下的行为,都没有证据。
“在通道的整个生命周期里,只需要把两笔交易提交到区块链上去挖:注资交易和结算交易。”
“In the entire lifetime of the channel, only two transactions need to be submitted for mining on the blockchain: the funding and settlement transactions.”
Second-Layer Applications › State Channels—Basic Concepts and Terminology查看原文 →
全书概念导图
5 组概念:通俗的叫法、一句话解释,以及原书自己的用语。
1 · 没有中间人的信任
- 一张由平等对等节点组成的扁平网状结构,没有人掌管
- 一张扁平的对等节点网,没有服务器、权威或层级,通过延伸工作量最大的链,收敛到同一份交易历史;它的精密源于许多简单的节点遵循简单的规则。原书用语: Decentralized trust network
- 你自己的软件重放全部历史,所以你不必信任任何人
- 你自己机器上的软件,从创世区块往后,独立地按每条规则重放每一笔交易和每个区块,建立内存池,监督矿工,并支撑共识;它是安全设计应当由此向外构建的、最不复杂的核心。原书用语: Full node validation as root of trust
- 手机可以检查一笔支付,而不必存储整条链
- 根据默克尔路径和其上的工作量,而不是验证整条链,来确认一笔支付,由紧凑区块中继、布隆过滤器和哥伦布-莱斯编码的紧凑区块过滤器支持,它们发送标识符或摘要,而不是完整的数据。原书用语: Lightweight verification and bandwidth-saving encodings
- 区块内容折叠成一个哈希,所以证明保持得很小
- 一棵双重 SHA256 哈希的二叉树,把一个区块的所有交易压缩成一个 32 字节的根,其中大约 log2(N) 个哈希就能证明任何单笔交易被包含。原书用语: Merkle tree and merkle path
2 · 币只是签名的记录
- 币只是你指回的未花费输出
- 一笔交易通过出点花费先前的输出,并创建新的、离散的可花费块——包括找零,因为输入不能被部分花费——让每个全节点成为一个未花费输出的数据库,未花掉的那部分差额作为手续费归矿工。原书用语: Inputs, outputs and the UTXO set
- 谁握着密钥谁拥有钱;没有客服台
- 持有私钥就是所有权的全部,协议对丢失或泄露没有任何补救,这就是为什么密钥要离线保管,并通过多重签名分散到不同的人和地方。原书用语: Keys as bearer ownership and distributed custody
- 一个助记词就能重建你将来需要的每一把密钥
- 一个种子加一个可重复的算法,就能重新生成无限的密钥树,备份为 12 到 24 个人类可读的词,外加一个可选的密码短语;扩展密钥携带链码,只含公钥的推导为仅观察的前端供数,而路径要么是 BIP 隐含的,要么记录为输出脚本描述符,在扫描间隔上限之内。原书用语: Deterministic hierarchical derivation and seed backup
- 地址是可重复使用的标签,可能泄露你是谁
- 对密钥或脚本承诺的、面向人的一连串编码——Base58check、压缩密钥、Bech32 和 Bech32m 见证程序——每一个都修补了先前的缺陷,包括当攻击者能影响被承诺的输入时,碰撞余量降到约 2^80;重复使用让观察者能把支付关联起来,而且一旦某个地址被识别出来,过去的也就被识别了。原书用语: Address encoding and identity linkage
3 · 始终可检查的规则
- 一种没有循环的小语言,决定一次花费是否被允许
- 一种类似 Forth 的栈语言,没有循环,没有外部状态,输出脚本陈述花费条件(授权),输入脚本提供满足条件的数据(认证),所以验证成本有界,每台机器都得出相同的裁决。原书用语: Script: stateless authorization language
- 签名证明对密钥的控制,而且必须覆盖确切的数据
- 椭圆曲线乘法正向容易、反向不可行,所以只有密钥持有者能签名;附加的 SIGHASH 字节确定承诺哪些字段,Schnorr 的线性性加上 Fiat-Shamir 挑战,产生无脚本的多重签名和门限签名,代价是密钥抵消攻击和 nonce 重用攻击。原书用语: Digital signatures from ECC to Schnorr aggregation
- 把签名移出 txid,就不会让 ID 变来变去
- 一笔未确认的花费可以被重新编码成不同的 txid,破坏预签名交易的链条;隔离见证,一次软分叉,把授权数据移出 txid 的计算,并改变签名的承诺哈希。原书用语: Malleability and segregated witness
4 · 挖矿取代了中央银行
- 猜哈希花费电力,赚得下一个区块
- 把区块头对着一个浮动的目标做哈希,直到结果落在它以下——找起来难如登天,检查起来便宜,重做起来昂贵——目标每 2016 个区块重新调整一次,使区块仍大约每十分钟出现一个。原书用语: Mining, proof of work and difficulty adjustment
- 新币付给找到区块的矿工
- 区块里由矿工创建的第一笔交易不花费任何输出,支付新创造的币加手续费,补贴每 210000 个区块减半,趋向于零,总量上限略低于 2100 万。原书用语: Coinbase transaction and block subsidy
- 上面每多一个新区块,逆转就远为更不可能
- 叠在一笔交易之上的每个区块,都让少数派攻击者的改写呈指数地更不可能;因为一个高度仍可能被争夺,币基奖励要等 100 个区块才可以花费。原书用语: Confirmation depth and reorganization risk
- 共识由运行同样规则的机器涌现出来
- 全网范围的一致,从许多节点上遵循相同规则、各自独立运行的过程中显现出来,没有投票,也没有固定的决定时刻;交易在区块中的拓扑顺序,才是消除双花的东西。原书用语: Emergent consensus
5 · 不改规则的增长
- 复杂的花费条件可以藏在一个短哈希后面
- 一个 t-of-k 或其他复杂的条件,藏在一个哈希后面,所以付款给它看起来像一个普通地址,赎回脚本在花费时才揭示;可证明不可花费的 OP_RETURN 输出记录数据,而不进入 UTXO 集。原书用语: Pay to Script Hash, multisignature and data outputs
- 花费可以被锁定,直到某个设定的时间或延迟过去
- 编码在输入的四字节序列字段里的相对延迟,对照最近十一个区块的中位时间戳来评估,而不是对照任何单一声称的时钟。原书用语: Timelocks and consensus time
- 通道把支付移到链下,由链来支撑
- 建在比特币之上的系统,组合它现有的保证——一致性、原子性、完整性、一次性封印、时间锁——而不改变共识;双方交换未发布的不对称承诺交易,其撤销密钥和相对时间锁会惩罚发布过时状态的行为,所以只有注资和结算上链。原书用语: Second layers and payment channels
值得停下来的段落AI 陪读
几处值得停下来的原文,每处附一句它为什么对全书要紧。
“币隐含在把价值从花费者转给接收者的交易之中”
“The coins are implied in transactions that transfer value from spender to receiver”
查看原文 →化解了全书其余部分所围绕的那个对象——没有币,只有被验证的转移,这就是为什么第6章可以说一笔交易是一次数据库更新。
“权威的数据——不是因为某个强大的实体指定它们为权威,而是因为你的节点独立地验证了它们”
“data which is authoritative—not because some powerful entity designated it as such but because your node independently verified it”
查看原文 →关于权威在这个系统里去了哪里的最干净的一句话:从机构转向本地计算,这正是第3、7、10章都在落实的东西。
“拥有能签署交易的密钥,是花费比特币的唯一前提”
“Possession of the key that can sign a transaction is the only prerequisite to spending bitcoin”
查看原文 →占有即所有,是产生全书整个风险面的前提,从第5章的种子备份,到第13章持有者凭证式的宿命论。
另外 8 条批注
“因为这样的重新计算需要巨大的计算量(因此也需要巨大的能耗),一条长长的区块链的存在,使得改动区块链的深处历史变得不切实际”
“Because such a recalculation would require enormous computation (and therefore energy consumption), the existence of a long chain of blocks makes the blockchain’s deep history impractical to change”
查看原文 →“不切实际,而非不可能”,是全书最重要的限定语——它把比特币的安全,从数学上的保证变成了一个价格,而第12章和第14章随后就在花这个价格。
“不可变性由能源来担保”
“Immutability is underwritten by energy”
查看原文 →五个字,点出了全书每一个不可变性主张背后的抵押品,并承认这个保证是一份能源预算,而不是一条定律。
“他将不得不在两者之间选择:用它去欺诈别人,偷回自己的付款,还是用它来生成新币”
“he would have to choose between using it to defraud people by stealing back his payments, or using it to generate new coins”
查看原文 →白皮书的基础,原来是一个关于理性贪婪的假设,这是书里后来再多工程也无法修补的唯一公理。
“如果没有办法为等价的交易创建新的签名,那么预签名交易中正在花费的钱就永久丢失了。”
“If there’s no way to create a new signature for an equivalent transaction, then the money being spent in the presigned transaction is permanently lost.”
查看原文 →表明为什么兼容性是一种伦理约束,而不是技术偏好:一次规则变更可能悄悄毁掉资金,这解释了贯穿第6、7、12章的软分叉纪律。
“这确保这种语言不是图灵完备的,意味着脚本的复杂性有限,执行时间可以预测。”
“This ensures that the language is not _Turing Complete_, meaning that scripts have limited complexity and predictable execution times.”
查看原文 →以无能为设计目标——全书反复出现的逻辑的最清楚例子:规则必须能被敌对的陌生人廉价而一致地检查。
“寻找区块的竞赛让最大的矿工占优势,所以它们的作用与比特币根本的去中心化背道而驰”
“Block-finding races give the advantage to the largest miners, so they act in opposition to Bitcoin’s essential decentralization”
查看原文 →揭示了延迟工程是政治性的:第10章里的优化选择就是去中心化的政策,第12章通过矿池触及的是同一个利害。
“工作量证明本质上是一个 CPU 一票”
“Proof-of-work is essentially one-CPU-one-vote”
查看原文 →老得最糟糕的主张,而书中后面关于 ASIC 和矿池的各章,就是对它的驳斥——抗女巫攻击的特性活了下来,平等主义没有。
“许多用户没有能力充分保护他们的密钥,于是被黑,一个接一个”
“many users are not able to adequately secure their keys and get hacked, one by one”
查看原文 →诚实的让步:去中心化并不能防止大规模的损失,它只是把损失零售化了——这是对书中对密码学的信心的人性制衡。
读后感AI 陪读
比特币的信任存在于你自己运行的软件里,而不是机构里
从头读到尾,《精通比特币》(第3版)不是一本关于钱的手册,而是一本关于把信任放在哪里的书,它的脊梁是把这份信任从机构转移到你自己运行的软件里。前言用它的切叶蚁把论点浓缩在小小的缩影里——复杂精密来自遵循简单规则的简单节点——全书随后以层层下降来证明它:第1–2章把一笔小小的支付戏剧化,直到 UTXO、找零、作为差额的手续费和确认深度是被挣得而不是被定义的;第3章让论点变得有形,让你克隆、编译并同步你自己的节点,使“你的数据是权威的,因为你验证过了”不再只是口号;第4–8章深入密钥、钱包、交易、脚本和签名,那里真正的叙事原来是一部修正史——base58check、压缩密钥、bech32、bech32m,从种子到分层推导再到描述符,隔离见证修复 txid 对输入脚本的承诺,P2SH 让位于 MAST,最终是 taproot 那一把可调整的密钥;第9–12章爬回经济学与政治——手续费是一场易逝拍卖中的密封出价,一张扁平的网状结构必须在不引入信任的前提下削减延迟,不可变性以重新计算的工作量证明来定价,而共识的改变是矿工、开发者、钱包、交易所、商家和用户之间的协调,而不是谁都能拨动的开关;第13–14章然后问你在其上构建什么,安全被转移到作为持有者的个人身上,而闪电网络把基础层的保证,组合成通道、可撤销承诺、HTLC 和洋葱路由。结尾的白皮书附录用一份平淡的协议备忘录,把一场货币革命呈现为一个双花的修复,完成了闭环。书中最尖锐的判断,是那些以让步的口吻说出来的:挖矿这个名字是误导,因为币是手段,去中心化的验证才是目的;“不切实际去改动”是一张价签,不是一把锁;轻量客户端能证明一笔交易存在,却永远无法证明某笔不存在;手续费市场和内存池限制孕育了交易钉住,它恰恰威胁最后一章所赞颂的、时间敏感的第二层协议;数据丢失而非失窃,才是永久丢失比特币的首要原因;以及 ECDSA 留在比特币里的原因是法律上的,而不是密码学上的。书最弱的地方,是把这些取舍叙述为净收益时——个人自己保障安全被描述为解放,而它自己的例子读起来却像是无上限责任的转嫁——最强的地方,则是它在每一期里干脆点出价格的时候。我要对读者说的是:别把它读成产品导览,也别只读你感兴趣的章节,因为论证是累积的,每一层的优雅,只有对照它被建来修复的那个具体失败,才看得懂。哪怕你再也不运行节点,也要运行一次第3章里的节点;把第5章里测试备份的指示当真;并且把每一处看似聪明的东西——隔离见证、taproot、CPFP carve out、紧凑区块过滤器——都读作伤疤组织。回报不是你会知道比特币怎么运作,而是你会内化它那一个可迁移的习惯:本地验证,把每一份便利都当作一笔信任的购买,并且始终问问是谁在付钱。
网络书评怎么说
在豆瓣和英文书评网站上,读者一致认为这是一本对比特币内部机制——密钥、钱包、交易、脚本、区块链和挖矿——的深入技术性论述,组织得很好,很有价值。几位中国读者提醒说它需要编程背景,有一位说自己只看懂了不到 5%,另一位说它已经过时;英文书评人推荐它给懂技术的读者,但不适合普通用户。
综合已发表书评的看法;不展示评分,完整书评请点来源链接。
来源与授权
CC BY-SA 4.0原书
- 《精通比特币:开放区块链编程》(Mastering Bitcoin: Programming the Open Blockchain)第三版,作者 Andreas M. Antonopoulos、David A. Harding,采用知识共享 署名-相同方式共享 4.0 国际许可协议(CC BY-SA 4.0)。Copyright © 2023 David Harding;此前版本 © 2014、2017 Andreas M. Antonopoulos LLC,© 2018 aantonop Books LLC。免费阅读原书 · 许可证
- 本页由 FeedLitra 撰写的文字(摘要、批注、读后感)按 CC BY-SA 4.0 授权。
- 本页的引文中文译文属于原作的改编作品,按同一协议(CC BY-SA 4.0)授权。
- 摘要、论点、批注和读后感由 FeedLitra 根据全书原文 AI 辅助生成,引文已对照原文核对。最近更新:2026 年 10 月 21 日。
在 FeedLitra 里一边读《精通比特币:开放区块链编程》,一边看这些卡片。
开始读书