1
acess OP (因为万恶的和谐,必须把文字拆开,看看哪里触发了和谐,抱歉)
|
2
acess OP 不过,幸运的是,对于现在最通用的 BIP39/44/49/84 钱包来说(不幸的是,最“官方”的 Bitcoin Core 目前还不是这个体系,尤其是有些开发者很抵制 BIP39 助记词,哎),不同的地址类型需要走不同的 HD 推导路径,不会出现一个公 /私钥被用到多种不同地址身上的情况。
只要你自己不自找麻烦,不把单个私钥或公钥手动导出后瞎折腾(换句话说,如果你瞎折腾了,那就可能出现问题,主要就是,你自己折腾出来的新地址,只能在你自己折腾的非标准钱包里看到交易记录和余额;而在标准的钱包里扫描不到,就好像丢了币一样),那还是: [一个私钥]<=>[一个公钥]<=>[一个地址] |
3
acess OP 还是 1-1 对应,还是那么简单清爽——虽然……
|
4
acess OP ……虽然,你给钱包导入 1 个 HD 助记词(或者叫 HD 种子)后,还是会:
|
5
acess OP (1)生成好多个地址;
(2)每次无论是收款还是付款,都会换(生成)一个新的地址(但是别怕,只要 HD 种子备份好了,这些地址都可以恢复出来); (3)而且这些地址还分 3 种: |
6
acess OP 第一种:1 开头的 P2PKH 地址,最老、最经典、最通用;矿工费没有折扣所以最贵。
(公钥当然是压缩公钥。P2PKH 可以用非压缩公钥,但是现在一般都不用了。另外下面提到的隔离见证还是禁用压缩公钥的) |
7
acess OP 第二种:3 开头的 P2SH-P2WPKH 地址,又叫 P2SH 封装隔离见证地址,或者叫“兼容”隔离见证地址。
兼容性和第一种差不多; 矿工费因为享受了折扣,所以(在转出时)比第一种便宜不少,但是因为 P2SH 封装本身也要占字节数,所以矿工费仍然比第三种贵; |
8
acess OP 第三种:bc1 开头的 P2WPKH 地址,又叫 Bech32 地址,或者叫“原生”隔离见证地址。
前两种地址都是中本聪设计的 Base58check 编码,大小写混合; Bech32 编码是新设计的,不含混合大小写,要么全大写要么全小写。 因为 Bech32 编码是新设计的,所以存在兼容性问题:老钱包不识别新地址,于是老钱包(在操作上)就不能转账给这种新地址——把钱包升级到支持 Bech32 的新版,或者把私钥 /助记词导出,再导入给支持 Bech32 的其他钱包,就可以了。 新钱包从新地址转给老钱包是没问题的(顶多就是零确认看不到,进链确认了就能看到进账了)。 |
9
acess OP 下面展开说说输出脚本这个梗……
|
10
acess OP 1 开头的 P2PKH 地址,实际上对应了一个“锁定脚本”,它规定了,在满足什么条件下,可以把币“解锁”、转(花)出去。
如果条件不满足(比如,你没给出有效的数字签名;或者是锁定时间还没到期,等等),那这笔交易就是非法的,不能打包进链,哪个矿工敢打包,大家就都不承认他挖的区块。 这个锁定脚本的写法,很显然是很自由的……但是如果你写的不是标准的脚本,那按理说就没有对应的地址可以表示这个脚本了。 |
11
acess OP 于是,很久很久以前(没记错的话是 2012 年),比特币引入了一个新功能,P2SH 。
|
12
acess OP 无论你的锁定脚本写得多么乱七八糟,都可以哈希一下,然后,这个脚本的哈希值就可以用一个 3 开头的地址来表示。
3 开头的地址——看看,有地址了!无论多么乱七八糟的锁定脚本,都可以用一个标准的、3 开头的地址来表示。 |
13
acess OP 这个脚本哈希值就可以代表你原先写的那个脚本,这种情况下,哈希之前的锁定脚本就改叫“赎回脚本”( redeem script )了。
未来要把币“解锁”转出去的时候,不仅要提供“解锁”的条件(一般就是数字签名),还要把“赎回脚本”的原文一同给出。 大家把你给出的赎回脚本进行哈希,和当初的脚本哈希比对,结果一致,然后就按照赎回脚本规定的步骤,去验证币能不能“解锁”花出去。 |
14
acess OP (其实 P2SH 是把原先存在的一种很鸡肋的输出脚本语义改变了……这种很鸡肋的输出脚本,在比特币引入 P2SH 功能之前,只走到“把你给出的赎回脚本进行哈希,和当初的脚本哈希比对,结果一致”这一步,就算验证通过了。这种情况,乍一看,好像是“输入密码即可提款”,很简单,但没有实用性。为什么没有实用性?因为任何人都可以把交易输出里的收款地址篡改成自己的,篡改完了交易仍然有效。P2PKH 就不是这样,交易输出是受数字签名保护的,篡改了输出,交易就无效了。总之,P2SH 用一种很 hack 的方式,把之前几乎无用的一种输出脚本重新定义,改进了现在广泛使用的新功能)
|
15
acess OP (楼上“P2PKH 就不是这样”这里没打错,我就是拿 P2PKH 举个例子,和 P2SH 的前身做一个对比)
|
16
acess OP (哎,14 楼还是有一处打字错误,纠正一下:“改进 [后就变成] 了现在广泛使用的新功能”,抱歉)
|
17
acess OP 然后回到主贴提到的:
“未来激活了 taproot,公钥可以和脚本哈希合体,里面还可以藏入……额……嵌套多层的脚本哈希……” 乍一看很可怕。但是,只要明白了 P2SH 是咋回事——无非就是,先登记合同的哈希值,未来要按照合同内容执行时,再提供完整的合同全文——那就会明白,taproot (这里不单指 taproot 本身,还包括了 MAST )并不是吓人的复杂怪物。 (不过老实说楼主也没亲自测试过 taproot,可能很多地方还有误解,轻喷) |
18
acess OP 首先,P2SH 不是用来封装锁定脚本的么,实际上都被大家用来封装什么了呢?
大多数时候,都是多重签名(其次就是隔离见证)。 一个地址,被多把私钥共同控制。 M of N 多重签名,就是一共有 N 把私钥参与,其中至少 M 把私钥签名后,就可以把币花(转)出去。 |
19
acess OP 实际上 P2SH (以及隔离见证改进版的 P2SH,也就是 P2WSH 。P2WSH 也是 bc1 开头,但是比 P2WPKH 更长)用到多重签名上还存在一个陷阱:
如果你把币存到了 2of3 多重签名地址上,但是只备份了其中两把私钥, 那么不好意思, (如果你把设置好的钱包文件删了)你的币丢了,永久丢失,谁也找不回来。 欸,不是 2of3 么,2 把私钥不是够了么,怎么会找不回来呢? 因为,要从 P2SH 地址里把币花出去,你不仅需要用 2 把私钥签名,还要知道被哈希的那个赎回脚本的完整原文是什么。如果你不知道第三把私钥对应的公钥,那也就等于你不知道赎回脚本。 当初建立多重签名钱包的时候,肯定是三个公钥都参与进来,才得到赎回脚本,然后赎回脚本哈希后就可以得到 3 开头的 P2SH 地址。 很显然,从脚本哈希是不能反推出脚本原文的,包括公钥。 如果你既没有赎回脚本本身,又没有第三把私钥对应的公钥(用这个公钥很显然可以重建赎回脚本),那就回天乏术了。 |
20
acess OP taproot 本身,就是说,一个公钥(这里需要配合将来要支持的 Schnorr 数字签名,而不是现在用的 ECDSA 数字签名),你看来看去,怎么看,它都只是一个公钥;但实际上,它不止是个公钥,这个公钥里还隐含了一个哈希值。
|
21
acess OP 19 楼提到的陷阱,是不是在 taproot 里能避免,这个老实说我还不是非常确定,毕竟楼主我是半桶水;但是 taproot 能干啥,我应该还是知道的。
首先复读一下,P2SH 是啥样的? 先登记合同的哈希值(脚本哈希),未来要按照合同内容执行时(把币花出去),再提供完整的合同全文(赎回脚本)。 然后,taproot 又是什么情况? 前文不是提到,公钥里可以藏一个哈希么,很显然,这个哈希可以是脚本哈希啊,于是就可以把 P2SH 的功能包括进来了。 然后,即便是把哈希藏到公钥里,只要交易打包进链,那“合同全文内容”还是固定了,改不了了。 但是,没关系。重点来了—— taproot 的这个公钥,不仅可以藏哈希;归功于 Schnorr 数字签名的神奇数学性质,这个公钥本身,还可以是多个公钥“合体”变成的。 然后,只要合体前的多把私钥全部都签名了,那么就可以无视(作废)掉当初藏进去的那个脚本哈希。 欸,作废了?那还藏这个脚本哈希进去有啥用? 有用啊。 如果多把私钥的主人们并没有全部达成一致意见,出现了争议,那就可以把当初订立的合同(赎回脚本)重新拿出来,对外出示,还是可以按照当初订立的合同来执行。 (这里也存在不少遗憾,比如这个神奇的 Schnorr 签名只能在所有人一个不落下全部都达成一致的情况下才好用;光靠 schnorr 签名本身,并不能实现“少数服从多数”的多重签名;(理论上)顶多只能实现反过来的“多数服从少数”。想要“少数服从多数”,还是得靠脚本) |
22
acess OP 到了这里,其实“嵌套多层的脚本哈希”是啥,也许即便我不说,可能你大概也明白了。
因为有神奇的 schnorr 签名加持,在[所有人一个不落下全部都达成一致意见的情况下],就可以无视当初藏进公钥的那个脚本哈希,不用出示完整的赎回脚本。 如果碰到了需要出示完整赎回脚本的情况呢? 脚本里,其实还可以包含一个公钥,这个公钥乍一看,怎么看都只是个公钥,实际上,它里面藏了一个脚本哈希…… 这个脚本哈希呢,在需要出示脚本原文的时候,里面其实还可以包括一个公钥,这个公钥乍一看,怎么看都只是个公钥,实际上,它里面藏了一个脚本哈希…… …… 嗯,就是这样,套娃了。 据我所知,(与 Schnorr 签名结合使用的) MAST 就是这么一回事。 而且,很容易想到: 就像代码里的 if then else,两个分支里只有一个会执行,不同条件执行不同的分支; MAST 也是类似的,而且,你只需要出示被执行的那部分代码,没执行的那部分,你不用出示,然后大家就都只能看到哈希,看不到原文。 |
23
acess OP 最后,很多时候 taproot 被宣传成“比特币的隐私功能”
如果我没理解错,这其实和很多人预想的不太一样。 |
24
acess OP taproot 的隐私性,据我所知只体现在两个方面:
(1)公钥里是不是藏了脚本哈希,外界看不出来,公钥和公钥看上去长得都很像,分不清彼此。所以,存在“可互换性”方面的好处。 (2)MAST 里只需要披露被执行的那部分脚本原文,不被执行的就可以不披露,外界只能看到哈希值,看不到原文。 |
25
acess OP 额,怎么说呢,和绝大多数人脑补的匿名性、不可追踪性什么的,好像不怎么能挂得上边(虽然第(1)点涉及“可互换性”,勉强挂得上边吧)……不知道是不是我了解不到位。而且 taproot 未来还是要通过软分叉实现,换句话说,taproot 本身,相对之前已经存在的 P2PKH 、P2SH 、P2WPKH……这些,就已经是又一个截然不同的、新的地址类型——不同的地址类型其实是对“隐私”/“可互换性”不利的,这恰恰就是 taproot 想要缓解的问题。
|
26
acess OP 换句话说,只有未来所有人都用上 taproot 了,taproot 的第(1)点好处才能完全体现;然而哪怕是现在,还有相当比例的人很守旧,连隔离见证都不愿意用(或者说,不知道怎么才能启用)。
|
27
acess OP 本来 schnorr 签名理论上还可以实现 CISA ( cross-input signature aggregation,跨输出签名聚·合),看上去对 coinjoin 很有用
|
28
acess OP (可以大幅节省字节数,N 个人一起混币,交易里只占一份数字签名的字节数,而不是 N 份),但 CISA 貌似也还是没有实现……
|
29
yqrm 2021-04-22 15:48:58 +08:00
10 年老 BTCer 来挽尊😂
|
30
zealic 2021-04-23 01:00:21 +08:00
楼主对 BIP39/44/49/84 理解的很深入。
Taproot 这里描述的很好,可以进一步理解其工作方式。 从另一个角度上考虑,Schnorr 的所有人签名并且不暴露赎回脚本这个功能也是非常有用的,更多的可能性不会在于钱包方面,而且和其他链如以太、波卡进行跨链交互,甚至多链交互。 这种跨链合约通过代码保证,所有人的全签名又可以保证不同的跨链智能合约进行合约嵌套组合(比如 AAVE 的闪电贷),可以实现非常复杂有趣的玩法,当然可能产生天量 GAS 费,因此这个设想还是需要 ETH 2.0 的支持。 |