BTC 学习笔记连载(10)——钱包和助记词
转载请注明出处~
1991年9月19日,一对德国登山夫妇途径阿尔卑斯山区时偶然发现了一具5300多年前的遗体,阿尔卑斯雪山环境将其尸体衣物完整冰冻了几千年,因为是在奥茨山谷被发现的,故科学家称其为奥茨冰人。
奥茨冰人穿戴整齐,靴子由熊皮和鹿皮制成子并内填稻草,绑腿、腰带和外套是用驯化的山羊皮制成,斗篷由鹿皮等多种毛皮混搭拼贴而成,头戴熊皮帽。随身携带着两只断裂的箭头、一把小匕首、一把打孔器、一把用来割菜和打火的刮削器,外加一把修整石器的鹿角锥、弓和箭,而最特殊的是一把象征着奥茨地位的杉木铜斧(现被完好保存在大英博物馆),冰人还随身携带了两个皮质荷包,其中一个装着新鲜的枫叶,另一个装着生火用的炭,这可能是迄今为止人类发现的最远古的“钱包”。
奥茨冰人所置身的时代钱包并不用来装钱,而那个时候的钱也并不是现代意义的money,食物或生存所必须才是硬通货,所以在皮包里存放的往往是外出所需的食物及用于生活物品。专注于研究古希腊历史的学者A·Y·坎贝尔曾解释古代文学里常出现的“wallet(钱包)”是穷人外出时随身携带的干粮包,以应对外出奔波时所需要的体能。
图左为公元10世纪左右巴比伦地区出土的钱包,现藏于圣迈克尔大学教会。图右为11世纪的圣詹姆斯像,身上背着贝壳装饰的钱包。那个时期的钱包以纵向为主,基本都是挂在腰带上或者背着,小的和今天的钱包类似,一旦要出远门就得背个大钱包。可以看出当时的钱包已经有一定的装饰效果了。
各种文物、雕像暗示,直到15世纪的这三百多年,西方的钱包其实都没什么大的变化。
中国古代有“宽袍广袖”一词,从各种古装电视剧就可以看出,钱包就藏在这“广袖”中,一般广袖里边会缝一个倒梯形口袋的“钱包”,可以揣一些碎银、书信和银票,空间不大却着实能装,“袖珍”一词就因此而来。但最适合放置钱物的袖子是琵琶袖,因为外形腋部较窄、大袖小口,形似琵琶而得名。
人民是穿不起权贵阶层的宽袍广袖的,一身短褐容不下袖袋,于是外出时会肩披褡裢。褡裢是一种两头缝合中间开口的四方形布袋,可以直接搭在肩上,也有样式小巧的可以直接挂在腰带上。我们常常在古装电视剧里看到的,商人、郎中们走街串巷,出远门在骡子背上挂的一些比较大的包裹都可以叫褡裢。直到明清时期褡裢依然是底层人民的必备钱包。
柏林出土15世纪末期华丽皮雕钱包,钱包两侧有用于安装挂带的位置,很明显这种扁形钱包已经是为了存放银币和金币之用。
然后陆续出现了各种荷包、手包、腰包、金属制硬币钱包等,直到纸币流行后男式钱包再也没有回到过袋子的形状,而女式袋状钱包一直流行到20世纪。
随着银行卡、信用卡的普及,国际标准化组织(ISO)对四种卡尺寸进行了统一规定,身份证、银行卡、驾照的卡片比例是接近1.618:1,具体尺寸为85.60×53.98毫米,带有多个固定尺寸“卡槽”的现代折叠钱包走上了标准化之路。这方便了银行卡在不同国家和银行的机器上使用,对于钱包生产商来说也方便生产世界通行标准卡槽的钱包。
2010年后移动互联网爆发,钱包的重要性逐渐被手机取代,2015年微信在春晚带起了“红包”潮,也带起了整个移动支付浪潮,微信支付、支付宝遍布大街小巷,小商小贩一个二维码走天下,猛地发现我也很多年没有用过钱包了,取而代之的是微信支付、支付宝等电子钱包。
电子钱包又叫数字钱包,一般指允许个人进行电子金融交易的电子设备或在线服务。无论是在台式电脑购买商品,还是用手机下单淘宝,又或是打车出行扫描二维码支付,背后都有电子钱包支付系统地支撑。电子钱包与个人的银行账户相连,通过实现绑定还可以将保险单、医保卡、手机账单、水电煤气费等代扣代缴关联,可以说是方便到极致。
钱包?账户?
本篇不是来分享钱包发展史的,而是对比跟现代电子钱包的一个本质问题:
一旦钱存到银行,就不在自己口袋了。
我们把钱存到银行之前需要先在银行开个账户(对应的就是银行卡正面的卡号),这个账户记录了每个存款人有多少钱,以及消费记录。银行系统也支持各种第3方支付应用,只要用户授权就可以消费自己在银行账户里的钱。虽然我们还没有遇到过,但一旦黑天鹅事件发生,银行遭到挤兑,你有可能取不出自己的钱。
那么你在手机上的这些微信支付、支付宝,或者银行App,网文叫的电子钱包,它是钱包么?
显然不是!
我想有正常逻辑的人,都应该能区分钱包和账户2个概念吧!
在银行开的是账户,我们把钱暂时存放到银行账户里。
在任何中心化机构注册的都叫账户,存进去的钱都由中心化机构操控着,账户只是记录你的资产及消费而以。
那为什么我们把Crypto资产放到FTX、某资管App时,它叫Wallet呢?
我第一次对Wallet这个名字表示质疑的时候,专业的中心化机构理直气壮地觉得这为啥不是钱包呢!
你听过有谁的钱是焊死在钱包里提不出来的?
FTX就是!
只要你的钱是放在别人那里的,只要你的Crypto资产不是由你自己的私钥直接掌控的,本质上都不是钱包。
然后你说,我们这个叫托管钱包。
nm托管的都是账户,好吧!
至少 Binance、OK 还知道自己这个叫账户:
我不是为了纠结它叫什么,而是为了强化大家对隐私、个人资产、去中心化的认知,大家可以再回去读一读《BTC 学习笔记连载(6)——为什么会有比特币?》,理解一下The Cypherpunk Manifesto,理解一下比特币为什么会诞生。
我不相信任何中心化机构,人类诞生的这几千年历史里不变的只有人性!
钱还是应该放到自己的钱包里!
链上钱包
那我们平常使用的 Metamask、TP、Math、Trust、SafePal 等等这些链上钱包OK吗?
如果不考虑钱包开发者作恶、黑客攻击、漏洞、钓鱼等问题,是没有问题的。
**那比特币是放在钱包里的吗?**又或者网文曾经报道某某的比特币放在某个硬盘里,硬盘丢了就找不回来了的案例,比特币是放在硬盘里的吗?
其实都不是,比特币(包括其它币)即不是放在链上钱包App里,也不是存放在某个硬盘里,而是由全网千千万万个节点账本进行记录,本质上区块链账本记录的是历史交易,账户的余额由UTXO决定(下一篇会详细讲解),余额的所有权由私钥决定。
本质上钱包只包含私钥,而同一个私钥可以放在N多个钱包里。
这样任何人都可以在Metamask、TP、Math、Trust、SFP等N多钱包上展示/管理自己的资产,这些链上钱包只是一个存储和管理用户私钥的工具,你的币是放在链上的,没有私钥谁都拿不走!
我们只是通过钱包查看链上资产,使用私钥签名转账而以。
所以当我们将同一个私钥导入不同钱包的时候,我们只是通过不同的工具看到了我们链上的资产,而并不需要将币从A钱包转到B钱包。
那些丢掉硬盘里的比特币的人,本质上不是丢了硬盘中的币,而是丢掉了私钥。
私钥-助记词
前面那张图,私钥下方一栏是助记词。
什么是助记词?
我们平常使用链上钱包的时候,创建账号或导入账号的时候,大多数情况并没有要求我们导入256位的二进制私钥,也没有要求我们导入64位16进制私钥。
以创建账号为例,通常都是给我们生成了12或24个助记词:
的确管理和使用256位的二进制数、64位16进制数不够便捷,但这么几个单词跟私钥有什么关系呢?12个单词能有256位二进制数同等的安全性吗?
非确定性钱包、确定性钱包
再讲助记词和私钥之间的关系之前,我们先再了解2个概念。
什么是非确定性钱包?
中本聪认为地址的重复使用会将多个交易关联在一起,这样会不利于隐私,为了最大化保护个人隐私,比特币早期版本每次交易都会生成新的私钥,打一枪换一个地方。
Bitcoin Core客户端在首次启动时就会预先生成100个随机私钥,每个私钥只使用一次,这样的钱包就相当于一个随机生成私钥的集合,私钥之间没有任何关联,故称为非确定性钱包。随机生成的私钥都需要进行备份,如果交易太过频繁还需要经常性地备份新的私钥,否则钱包将变得不可用,比特币也容易丢失。
显然,这种方式的钱包难以管理和使用的,逐渐也就被确定性钱包所替代。
确定性指什么?
这里确定性指的是钱包包含的所有私钥都是通过哈希从种子单向派生出来的,只要种子确定派生出来的私钥和地址就都是确定的。
种子是一串随机生成的数字,这串数字结合索引、链码即可派生出其它私钥,只要备份好种子,即可恢复所有派生的私钥。种子也很方便在钱包导入/导出,这样在不同钱包之间也就可以轻松转移所有私钥了。
确定性钱包就是一个1对多的派生关系,可以很容易从单个种子派生出多个私钥,目前几乎所有钱包都在使用的是分层确定性钱包,即HD钱包。
分层确定性指的是啥?
HD钱包是由BIP-32标准定义的,基于种子私钥以树状结构派生,父私钥可以派生出一系列子私钥,子私钥又可以派生出一系列孙子私钥,就这样一直派生下去,一生二、二生三、三生万物!
HD钱包有2个天然的优势:
树状结构天然可以表达各种组织结构
比如公司不同部门、子公司、会计部门使用不同的分支;
也可以某个特定的分支用于支出,另一个分支用于收款;可以创建一系列公钥而无需知晓对应的私钥
这样HD钱包可以在安全性比较差的环境用于收款
如上图,HD钱包的主私钥是由一个种子派生的,如果这个种子是由一组标准化的英文单词生成,是不是就解决了抄录、钱包见转移、导入/导出等一系列易用性问题了。
这些英文单词就是我们前面提到的助记词,由BIP-39标准定义,今天我们使用的绝大多数钱包都使用该标准,甚至其它加密货币都可以互用这些助记词进行种子的备份及恢复。
这是怎么回事呢?我们来逐步拆解一下:
助记词和种子的关系
首先创建一个 128/160/192/224/256 位的随机数熵
如图我们以128位随机数为例对该随机数进行SHA256哈希,取前x位作为校验和
x = 随机数位数 / 32
128位随机数就是4位校验位将随机数+校验位合并到一起并按11bit进行分组
这里132bit刚好能分12组将每组的11bit映射到BIP-39英文单词表
BIP-39英文单词表就是一个K-value映射表
任何 128/160/192/224/256 位随机数最终都可以映射位12~24个BIP-39英文单词表里的单词最后通过秘钥派生函数PBKDF2派生出512位种子
这是一个2048轮的SHA512哈希运算,可见暴力破解的成本有多高
这里包含2个参数:助记词、盐
使用盐可以增加暴力破解的难度。
另一个重要目的就是为了引入密码,密码可以存储在大脑中作为第2个安全因子,这样即便助记词被盗也不会泄露种子。
如果没有使用密码,一般以“mnemonic”作为默认的盐。
这里我们可以看出,本质上还是通过随机熵源生成种子的过程,助记词只是方便我们存储、使用而以。
种子的取值空间是一个天文数字:2^512
任何试图暴力破解的行为都是徒劳的!
HD 钱包的派生过程
HD 钱包最早是由比特币社区提出,如今已经成为事实上的行业标准,BIP32中根据父节点派生子节点的方法被称为CKD(Child Key Derivation Function),CKD 根据3个重要参数去生成子节点:
父节点私钥或公钥
父节点链码(Parent Chain Code)
子节点序号(Child Index)
这个派生过程是怎样的呢?
我们先以父节点私钥的强化派生为例:
基于种子通过HMAC-SHA 512生成一个512bit的二进制数;
将512bit分成等长的2个256bit的二进制数;
左256bit为种子派生出来的主私钥
右256bit做为根节点链码根据主私钥通过椭圆曲线乘法生成主公钥;
再将父节点私钥、父节点链码、子节点序号作为参数,进行HMAC-SHA512得到另一个512bit的二进制数;
同样均分为L、R 两个等长的256bit二进制数父节点私钥 + L 做运算得到子节点私钥;
R 当做子节点链码;
根据子私钥通过椭圆曲线乘法生成子公钥;
这样就实现了从种子到多层私钥的派生,然后每一个私钥对应生成各自的公钥、地址。但其实也可以不这么搞,以其它任何方式只要是能确定性地生成256位私钥都可以。
细心的同学应该已经注意到,这个过程中SHA512的参数有一个32bit的索引,就是基于这个索引的取值空间才能在一个节点下派生出N多个私钥。强化派生使用2^31~2^32-1的索引码,这样任何一个节点私钥都可以派生出2^31个子私钥(常规派生占用了另外2^31个索引空间),然后任何一个子私钥又可以派生出2^31个孙私钥,然后一直这么派生下去。
理论上HD钱包可以派生出无穷无尽的私钥-公钥对!
扩展密钥
从上面私钥派生算法我们可以看到,只需要私钥、链码、索引号3个输入,私钥派生函数就可以创建该层级上的任意子私钥。
私钥 & 链码 两个部分组合在一起就叫扩展秘钥(extended key),即可扩展的秘钥。
很显然扩展秘钥就是由256bit私钥 + 256bit链码组成的512bit二进制数,实际上有2种扩展秘钥:
扩展私钥xpriv:私钥&链码组成,用于派生子私钥
扩展公钥xpub:公钥&链码组成,用于派生子公钥
扩展私钥可以创建一个基于该私钥节点的完整分支,而扩展公钥只能创建一个包含公钥的分支。这就为诸多不太安全的环境提供了解决方案:
公钥部署
基于扩展公钥进行部署,服务器或Dapp应用可以在没有私钥的情况下扩展公钥-地址分支,这些分支专门用于在不太安全的环境进行收款,由于这些环境没有涉及任何私钥,所以收到的比特币也暂时无法消费。
但是可以在另一个安全的环境,使用扩展私钥派生出相应的私钥消费这些比特币。
如图,这是《精通区块链编程》里的一张图示,这里我们可以看到2种生成子公钥的路径:
通过子私钥生成
通过父公钥生成
第1种方式没什么好说的,关键是第2种通过父公钥派生子公钥,从图示看是将父节点公钥钥、父节点链码、子节点序号作为参数,进行HMAC-SHA512哈希,这个图画得多少有点问题,按网上查找资料的说法这里应该是:
- left 256bit 和父节点公钥做运算得到子节点公钥
这个过程我把它拆解一下,看得更清楚:
左侧为通过父私钥生成子私钥
右侧为通过父公钥生成子公钥
这里如果索引都是0,那么派生出来的子私钥、子公钥都是同一层级的第1个私钥、公钥
这里我有个疑问,或者就当时我没搞懂吧:
左边的子私钥通过椭圆曲线乘法可以生成对应的子公钥
按书上、网文资料的逻辑,这个子公钥和右边扩展公钥派生出来的子公钥是相等的
怎么办到的?
基于哈希函数和椭圆曲线乘法的特性,这2个264bit的二进制数压根儿就不可能相等!
可能我理解得不对,希望搞懂的朋友能在Twitter上交流一下,给予一些指导。
即便这个是成立的,扩展公钥(xpub)方案也不安全:
如果某个子私钥被泄露,可以和父链码一块派生所有其它子私钥
子私钥与父链码可以推断父私钥。
《精通区块链编程》讲到位了应对这种潜在风险,HD钱包才从xpub改为前面讲的强派生函数,强派生打破了父公钥和子链码之间的关系,仅使用父私钥推导子链码,拥有链码并不能用来推算父私钥和姊妹私钥。
这里又给我整懵逼了,或者就当时我没搞懂吧:
xpub包含了链码,假设子私钥 1 已被泄露
所有绿色部分可以认为都是已知的这里如何通过已知的链码 + 子私钥 1 推断父私钥?
如何通过已知的链码 + 子私钥 1 派生其它子私钥?
因为这里是需要进行SHA512哈希的,通过《BTC 学习笔记连载(3)——Hash》我们知道哈希函数的特性Collision resistance,这里相当于试图暴力碰撞父私钥,怎么可能?
可能我理解得不对,希望搞懂的朋友能在Twitter上交流一下,给予一些指导。
可能确实有些东西没搞懂,网上资料又大多讲得模棱两可。
……
扩展秘钥使用Base58Check编码,即可穷送地在不同的兼容BIP-32标准的钱包之间导入/导出。了解了BIP-32、BIP-39,大家也可以自行了解一下BIP-44,BIP44 定义了逻辑上的层级结构,综合了BIP32的HD Wallet设计和BIP43 的Purpose约定,使得HD Wallet能够表达多币种、多账号等分类定义。
差不多到这里我们就基本了解了 助记词-私钥-公钥-地址 的整个生成过程:
无论怎样,最核心的依然是私钥!
但是要记住,助记词派生私钥的算法是确定的,所以丢了助记词就相当于丢了私钥!
钱包仅仅是一个承载私钥的工具!
不要使用不知名钱包!
一点延伸思考
平常我们使用 Metamask 的时候,不知道有没有同学发现,基于一个已有的账户,如果再点击创建账户,Metamask并没有给你生成新的助记词,而且还可以不停地创建多个账户:
这是怎么回事?这些后续生成的账户不需要私钥管理吗?
要不这个作为一个问题,自己思考一下?
提示:你将同一个助记词导入不同电脑的Metamak插件,然后点击创建账户分别增加多个账户,对比一下这些账户,我想你应该就能找到答案了。
然后我在提个问题:
之前有些朋友说:“咋感觉助记词都是些很熟悉的单词呢?而且感觉还很频繁地出现,有没有机会搞一些比较常见的单词,然后刚好碰上个大户?”
比如这样一些单词:about、action、above、access、act、all…bird、blood…cat、click、use…walk…zero、zone、zoo
这个说法显然是不行的!
行的话现在就不会用这种方式了,欧洲某实验室就组织了超级计算机实验碰撞比特币私钥,在N多年的尝试中也有偶尔碰撞出一些,但是都是一些资产比较少的账户,要想碰撞出孙割的私钥那几率比地球爆炸还要小。
为什么?留个作业推导一下!
如何选择钱包?
所有人在面对个人资产的时候无非2个考量,Crypto资产也不例外:
存储
使用
比特币要怎么存储才安全?
要怎样才能方便使用比特币?
当然存储比特币就是为了有朝一日能够使用它,而且这个问题我们也可以扩展到其它公链及币种,比如ETH、DOGE、PEOPLE、MATIC……
通过文章前面的推导,我们知道Crypto资产本身没有存储在任何钱包里,也没有存储在某个硬盘上,只要你不消费它就安静地躺在链上。
我们关心的是使用什么工具来管理它,本质上就是怎么管理私钥、管理助记词?
进而平衡这些管理方案怎么方便自己使用!
其实方案有很多,比如:冷钱包、热钱包、脑钱包、纸钱包、多签钱包,以及最近炒得比较火的MPC钱包。我们可以使用一台废弃的IPhone手机,去除SIM卡并且不连网,然后生成私钥或导入助记词,从而实现冷钱包的效果;也可以直接买一个硬件钱包;还可以只讲助记词抄录在纸上,而不在任何联网环境存储;甚至还可以在脑子里记住一个只有自己知道的句子,然后通过SHA256生成自己的私钥或通过HMAC-SHA512生成种子;
有非常多的方案可以选择,但这里面还有个重要的问题:
你有多少钱要管理?
这就是一个资产安全性和使用便捷性之间的权衡!
前面提到的方便使用,就是当我们想要交易做波段的时候是否方便?当我们想参与某个Defi挖矿的时候是否便捷?当我们想给朋友转账,想卖掉一些币补贴生活得时候是否能低成本的操作?
如果你只有5000刀的ETH,非要用冷钱包来管理,何必呢?还不如就放在币安或OK。
如果你又很大额的资产,又不会频繁使用,那偏向用硬件钱包来管理;
如果你的资产不是很多,可以直接考虑链上钱包+纸钱包;
如果你的资产很少,其实头部中心化交易所也可以考虑;
如果你的资产是分级的,可以每种方式都搭配这用;
所以一切都是看怎么规划和管理自己的资产!
另一个比较棘手的问题就是,我们身边很多资产损失的朋友,他们的资产丢失并不是因为私钥/助记词被盗,而是通过链上钱包签名授权了不该授权的交易,比如很多黑客、钓鱼攻击等。所以不要使用一些乌七八糟的钱包应用,也不要乱签名一些不知名的应用,不要老想着又去捡空投了,又有馅饼从天上掉下来了。往往不贪就不会被割!
但是还有个问题就是,无论这些方案怎么怎么适合,绝大多数用户还是搞不懂的,什么私钥、助记词、签名这些东西,脑壳痛啊~ 我们不可能通过给大家做个培训,就能解决这些小白用户对私钥对签名的认知的。
怎么办?
中心化!
还只能中心化,你不是搞不懂么,Binance、OK来帮你管理,这样有问题的时候你还找得到客服,然后你要交易的时候也很方便,你也不用担心怎么保管自己的私钥、助记词。唯一需要担心的就是中心化机构是否会暴雷!没办法,学不会就只能寄托于中心化“钱包”、只能寄托于更好的监管了。
但是我们从事Crypto或新一代的年轻人,一定要搞懂它的本质,选择最适合自己的方式,千万不要像这句名言一样:币还在,助记词丢了 TT
我在鹅厂是最后2年是做联邦学习、安全多方计算(MPC)的,最近听说一个创新的钱包方案就是MPC钱包,用户连助记词都可以不记了,找个时间研究一下再写一篇分享!
不过无论什么方案,都不能过度迷信易用性而牺牲安全性,不要拿自己的钱开玩笑!
OK,本篇就介绍到这里了。