说说为什么一个比特币私钥可以对应多个地址 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
acess
V2EX    Bitcoin

说说为什么一个比特币私钥可以对应多个地址

  •  
  •   acess 2021-04-22 03:13:27 +08:00 1678 次点击
    这是一个创建于 1638 天前的主题,其中的信息可能已经有所发展或是发生改变。
    楼主来半桶水瞎掰扯一下这个蛋疼的问题……


    (1)光是公钥就分两种:压缩和非压缩。现在一般用压缩的。

    于是,光是 1 开头的 P2PKH 地址,就有两个,因为压缩公钥和非压缩公钥哈希出来也不一样。


    (2)锁定脚本,或者叫输出脚本,这方面的写法几乎无穷无尽……虽然典型 /常见的也就那么几种。

    这个说来话长。

    不过到这里已经可以看到:

    2 种公钥×N 种输出脚本=……
    额,有点画美不看……

    而且,未来激活了 taproot,公钥可以和脚本哈希合体,里面还可以藏入……额……嵌套多层的脚本哈希……
    额……

    (又不知道哪里触发 V 站的和谐了,哎,跟贴吧一样难用,楼下继续)
    第 1 条附言    2021-04-22 04:51:28 +08:00
    前情提要: /t/772048
    30 条回复    2021-04-23 01:00:21 +08:00
    acess
        1
    acess  
    OP
       2021-04-22 03:14:44 +08:00
    (因为万恶的和谐,必须把文字拆开,看看哪里触发了和谐,抱歉)
    acess
        2
    acess  
    OP
       2021-04-22 03:14:59 +08:00
    不过,幸运的是,对于现在最通用的 BIP39/44/49/84 钱包来说(不幸的是,最“官方”的 Bitcoin Core 目前还不是这个体系,尤其是有些开发者很抵制 BIP39 助记词,哎),不同的地址类型需要走不同的 HD 推导路径,不会出现一个公 /私钥被用到多种不同地址身上的情况。

    只要你自己不自找麻烦,不把单个私钥或公钥手动导出后瞎折腾(换句话说,如果你瞎折腾了,那就可能出现问题,主要就是,你自己折腾出来的新地址,只能在你自己折腾的非标准钱包里看到交易记录和余额;而在标准的钱包里扫描不到,就好像丢了币一样),那还是:

    [一个私钥]<=>[一个公钥]<=>[一个地址]
    acess
        3
    acess  
    OP
       2021-04-22 03:15:33 +08:00
    还是 1-1 对应,还是那么简单清爽虽然……
    acess
        4
    acess  
    OP
       2021-04-22 03:15:45 +08:00
    ……虽然,你给钱包导入 1 个 HD 助记词(或者叫 HD 种子)后,还是会:
    acess
        5
    acess  
    OP
       2021-04-22 03:15:55 +08:00
    (1)生成好多个地址;
    (2)每次无论是收款还是付款,都会换(生成)一个新的地址(但是别怕,只要 HD 种子备份好了,这些地址都可以恢复出来);
    (3)而且这些地址还分 3 种:
    acess
        6
    acess  
    OP
      nbsp;2021-04-22 03:16:14 +08:00
    第一种:1 开头的 P2PKH 地址,最老、最经典、最通用;矿工费没有折扣所以最贵。
    (公钥当然是压缩公钥。P2PKH 可以用非压缩公钥,但是现在一般都不用了。另外下面提到的隔离见证还是禁用压缩公钥的)
    acess
        7
    acess  
    OP
       2021-04-22 03:16:21 +08:00
    第二种:3 开头的 P2SH-P2WPKH 地址,又叫 P2SH 封装隔离见证地址,或者叫“兼容”隔离见证地址。
    兼容性和第一种差不多;
    矿工费因为享受了折扣,所以(在转出时)比第一种便宜不少,但是因为 P2SH 封装本身也要占字节数,所以矿工费仍然比第三种贵;
    acess
        8
    acess  
    OP
       2021-04-22 03:16:28 +08:00
    第三种:bc1 开头的 P2WPKH 地址,又叫 Bech32 地址,或者叫“原生”隔离见证地址。
    前两种地址都是中本聪设计的 Base58check 编码,大小写混合; Bech32 编码是新设计的,不含混合大小写,要么全大写要么全小写。
    因为 Bech32 编码是新设计的,所以存在兼容性问题:老钱包不识别新地址,于是老钱包(在操作上)就不能转账给这种新地址把钱包升级到支持 Bech32 的新版,或者把私钥 /助记词导出,再导入给支持 Bech32 的其他钱包,就可以了。
    新钱包从新地址转给老钱包是没问题的(顶多就是零确认看不到,进链确认了就能看到进账了)。
    acess
        9
    acess  
    OP
       2021-04-22 03:18:50 +08:00
    下面展开说说输出脚本这个梗……
    acess
        10
    acess  
    OP
       2021-04-22 03:19:09 +08:00
    1 开头的 P2PKH 地址,实际上对应了一个“锁定脚本”,它规定了,在满足什么条件下,可以把币“解锁”、转(花)出去。

    如果条件不满足(比如,你没给出有效的数字签名;或者是锁定时间还没到期,等等),那这笔交易就是非法的,不能打包进链,哪个矿工敢打包,大家就都不承认他挖的区块。

    这个锁定脚本的写法,很显然是很自由的……但是如果你写的不是标准的脚本,那按理说就没有对应的地址可以表示这个脚本了。
    acess
        11
    acess  
    OP
       2021-04-22 03:19:20 +08:00
    于是,很久很久以前(没记错的话是 2012 年),比特币引入了一个新功能,P2SH 。
    acess
        12
    acess  
    OP
       2021-04-22 03:19:46 +08:00
    无论你的锁定脚本写得多么乱七八糟,都可以哈希一下,然后,这个脚本的哈希值就可以用一个 3 开头的地址来表示。

    3 开头的地址看看,有地址了!无论多么乱七八糟的锁定脚本,都可以用一个标准的、3 开头的地址来表示。
    acess
        13
    acess  
    OP
       2021-04-22 03:19:57 +0800
    这个脚本哈希值就可以代表你原先写的那个脚本,这种情况下,哈希之前的锁定脚本就改叫“赎回脚本”( redeem script )了。

    未来要把币“解锁”转出去的时候,不仅要提供“解锁”的条件(一般就是数字签名),还要把“赎回脚本”的原文一同给出。
    大家把你给出的赎回脚本进行哈希,和当初的脚本哈希比对,结果一致,然后就按照赎回脚本规定的步骤,去验证币能不能“解锁”花出去。
    acess
        14
    acess  
    OP
       2021-04-22 03:20:19 +08:00
    (其实 P2SH 是把原先存在的一种很鸡肋的输出脚本语义改变了……这种很鸡肋的输出脚本,在比特币引入 P2SH 功能之前,只走到“把你给出的赎回脚本进行哈希,和当初的脚本哈希比对,结果一致”这一步,就算验证通过了。这种情况,乍一看,好像是“输入密码即可提款”,很简单,但没有实用性。为什么没有实用性?因为任何人都可以把交易输出里的收款地址篡改成自己的,篡改完了交易仍然有效。P2PKH 就不是这样,交易输出是受数字签名保护的,篡改了输出,交易就无效了。总之,P2SH 用一种很 hack 的方式,把之前几乎无用的一种输出脚本重新定义,改进了现在广泛使用的新功能)
    acess
        15
    acess  
    OP
       2021-04-22 03:21:52 +08:00
    (楼上“P2PKH 就不是这样”这里没打错,我就是拿 P2PKH 举个例子,和 P2SH 的前身做一个对比)
    acess
        16
    acess  
    OP
       2021-04-22 03:23:12 +08:00
    (哎,14 楼还是有一处打字错误,纠正一下:“改进 [后就变成] 了现在广泛使用的新功能”,抱歉)
    acess
        17
    acess  
    OP
       2021-04-22 03:27:18 +08:00
    然后回到主贴提到的:
    “未来激活了 taproot,公钥可以和脚本哈希合体,里面还可以藏入……额……嵌套多层的脚本哈希……”

    乍一看很可怕。但是,只要明白了 P2SH 是咋回事无非就是,先登记合同的哈希值,未来要按照合同内容执行时,再提供完整的合同全文那就会明白,taproot (这里不单指 taproot 本身,还包括了 MAST )并不是吓人的复杂怪物。

    (不过老实说楼主也没亲自测试过 taproot,可能很多地方还有误解,轻喷)
    acess
        18
    acess  
    OP
       2021-04-22 03:35:05 +08:00
    首先,P2SH 不是用来封装锁定脚本的么,实际上都被大家用来封装什么了呢?
    大多数时候,都是多重签名(其次就是隔离见证)。
    一个地址,被多把私钥共同控制。
    M of N 多重签名,就是一共有 N 把私钥参与,其中至少 M 把私钥签名后,就可以把币花(转)出去。
    acess
        19
    acess  
    OP
       2021-04-22 03:41:52 +08:00
    实际上 P2SH (以及隔离见证改进版的 P2SH,也就是 P2WSH 。P2WSH 也是 bc1 开头,但是比 P2WPKH 更长)用到多重签名上还存在一个陷阱:

    如果你把币存到了 2of3 多重签名地址上,但是只备份了其中两把私钥,
    那么不好意思,
    (如果你把设置好的钱包文件删了)你的币丢了,永久丢失,谁也找不回来。

    ,不是 2of3 么,2 把私钥不是够了么,怎么会找不回来呢?

    因为,要从 P2SH 地址里把币花出去,你不仅需要用 2 把私钥签名,还要知道被哈希的那个赎回脚本的完整原文是什么。如果你不知道第三把私钥对应的公钥,那也就等于你不知道赎回脚本。
    当初建立多重签名钱包的时候,肯定是三个公钥都参与进来,才得到赎回脚本,然后赎回脚本哈希后就可以得到 3 开头的 P2SH 地址。

    很显然,从脚本哈希是不能反推出脚本原文的,包括公钥。
    如果你既没有赎回脚本本身,又没有第三把私钥对应的公钥(用这个公钥很显然可以重建赎回脚本),那就回天乏术了。
    acess
        20
    acess  
    OP
       2021-04-22 03:42:24 +08:00
    taproot 本身,就是说,一个公钥(这里需要配合将来要支持的 Schnorr 数字签名,而不是现在用的 ECDSA 数字签名),你看来看去,怎么看,它都只是一个公钥;但实际上,它不止是个公钥,这个公钥里还隐含了一个哈希值。
    acess
        21
    acess  
    OP
       2021-04-22 04:00:41 +08:00
    19 楼提到的陷阱,是不是在 taproot 里能避免,这个老实说我还不是非常确定,毕竟楼主我是半桶水;但是 taproot 能干啥,我应该还是知道的。


    首先复读一下,P2SH 是啥样的?

    先登记合同的哈希值(脚本哈希),未来要按照合同内容执行时(把币花出去),再提供完整的合同全文(赎回脚本)。


    然后,taproot 又是什么情况?

    前文不是提到,公钥里可以藏一个哈希么,很显然,这个哈希可以是脚本哈希啊,于是就可以把 P2SH 的功能包括进来了。

    然后,即便是把哈希藏到公钥里,只要交易打包进链,那“合同全文内容”还是固定了,改不了了。

    但是,没关系。重点来了
    taproot 的这个公钥,不仅可以藏哈希;归功于 Schnorr 数字签名的神奇数学性质,这个公钥本身,还可以是多个公钥“合体”变成的。

    然后,只要合体前的多把私钥全部都签名了,那么就可以无视(作废)掉当初藏进去的那个脚本哈希。

    ,作废了?那还藏这个脚本哈希进去有啥用?
    有用啊。
    如果多把私钥的主人们并没有全部达成一致意见,出现了争议,那就可以把当初订立的合同(赎回脚本)重新拿出来,对外出示,还是可以按照当初订立的合同来执行。

    (这里也存在不少遗憾,比如这个神奇的 Schnorr 签名只能在所有人一个不落下全部都达成一致的情况下才好用;光靠 schnorr 签名本身,并不能实现“少数服从多数”的多重签名;(理论上)顶多只能实现反过来的“多数服从少数”。想要“少数服从多数”,还是得靠脚本)
    acess
        22
    acess  
    OP
       2021-04-22 04:09:31 +08:00
    到了这里,其实“嵌套多层的脚本哈希”是啥,也许即便我不说,可能你大概也明白了。

    因为有神奇的 schnorr 签名加持,在[所有人一个不落下全部都达成一致意见的情况下],就可以无视当初藏进公钥的那个脚本哈希,不用出示完整的赎回脚本。

    如果碰到了需要出示完整赎回脚本的情况呢?

    脚本里,其实还可以包含一个公钥,这个公钥乍一看,怎么看都只是个公钥,实际上,它里面藏了一个脚本哈希……

    这个脚本哈希呢,在需要出示脚本原文的时候,里面其实还可以包括一个公钥,这个公钥乍一看,怎么看都只是个公钥,实际上,它里面藏了一个脚本哈希……

    ……

    嗯,就是这样,套娃了。
    据我所知,(与 Schnorr 签名结合使用的) MAST 就是这么一回事。

    而且,很容易想到:
    就像代码里的 if then else,两个分支里只有一个会执行,不同条件执行不同的分支;
    MAST 也是类似的,而且,你只需要出示被执行的那部分代码,没执行的那部分,你不用出示,然后大家就都只能看到哈希,看不到原文。
    acess
        23
    acess  
    OP
       2021-04-22 04:21:16 +08:00
    最后,很多时候 taproot 被宣传成“比特币的隐私功能”

    如果我没理解错,这其实和很多人预想的不太一样。
    acess
        24
    acess  
    OP
       2021-04-22 04:21:32 +08:00
    taproot 的隐私性,据我所知只体现在两个方面:

    (1)公钥里是不是藏了脚本哈希,外界看不出来,公钥和公钥看上去长得都很像,分不清彼此。所以,存在“可互换性”方面的好处。

    (2)MAST 里只需要披露被执行的那部分脚本原文,不被执行的就可以不披露,外界只能看到哈希值,看不到原文。
    acess
        25
    acess  
    OP
       2021-04-22 04:22:01 +08:00
    额,怎么说呢,和绝大多数人脑补的匿名性、不可追踪性什么的,好像不怎么能挂得上边(虽然第(1)点涉及“可互换性”,勉强挂得上边吧)……不知道是不是我了解不到位。而且 taproot 未来还是要通过软分叉实现,换句话说,taproot 本身,相对之前已经存在的 P2PKH 、P2SH 、P2WPKH……这些,就已经是又一个截然不同的、新的地址类型不同的地址类型其实是对“隐私”/“可互换性”不利的,这恰恰就是 taproot 想要缓解的问题。
    acess
        26
    acess  
    OP
       2021-04-22 04:22:16 +08:00
    换句话说,只有未来所有人都用上 taproot 了,taproot 的第(1)点好处才能完全体现;然而哪怕是现在,还有相当比例的人很守旧,连隔离见证都不愿意用(或者说,不知道怎么才能启用)。
    acess
        27
    acess  
    OP
       2021-04-22 04:23:17 +08:00
    本来 schnorr 签名理论上还可以实现 CISA ( cross-input signature aggregation,跨输出签名聚合),看上去对 coinjoin 很有用
    acess
        28
    acess  
    OP
       2021-04-22 04:23:24 +08:00
    (可以大幅节省字节数,N 个人一起混币,交易里只占一份数字签名的字节数,而不是 N 份),但 CISA 貌似也还是没有实现……
    yqrm
        29
    yqrm  
       2021-04-22 15:48:58 +08:00
    10 年老 BTCer 来挽尊
    zealic
        30
    zealic  
       2021-04-23 01:00:21 +08:00
    楼主对 BIP39/44/49/84 理解的很深入。

    Taproot 这里描述的很好,可以进一步理解其工作方式。

    从另一个角度上考虑,Schnorr 的所有人签名并且不暴露赎回脚本这个功能也是非常有用的,更多的可能性不会在于钱包方面,而且和其他链如以太、波卡进行跨链交互,甚至多链交互。
    这种跨链合约通过代码保证,所有人的全签名又可以保证不同的跨链智能合约进行合约嵌套组合(比如 AAVE 的闪电贷),可以实现非常复杂有趣的玩法,当然可能产生天量 GAS 费,因此这个设想还是需要 ETH 2.0 的支持。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4629 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 10:00 PVG 18:00 LAX 03:00 JFK 06:00
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86