Skip to content

Latest commit

 

History

History

16-bitcoin

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Bitcoin 面试题目

第一题: 简述 UTXO 模型


第二题:比特钱包有哪些地址格式,请简要说明


第三题: Pay-to-Taproot介绍与优势

Pay-to-Taproot(P2TR)是一种ScriptPubKey,它将比特币锁定在一个脚本上,允许用户向 Schnorr 公钥或各种其他脚本的 Merkle 根支付。表面上看,一个P2TR输出将比特币锁定在一个施诺尔公钥上,我们假设为Q。然而,这个公钥Q实际上是一个公钥P和一个公钥M的总和,M是由其他ScriptPubKeys列表的Merkle根计算出来的。P2TR 输出中的比特币可以通过发布公钥 P 的签名或满足 Merkle 树中包含的脚本之一来花费,前者称为密钥路径,后者则是脚本路径。虽然P2TR的输出可能有许多种方式,但只有被使用的那一种会被公开,这样可以为其他未使用的替代方案保持隐私。此外,由于Schnorr密钥聚合特性,公钥P本身可以是一个聚合密钥,公钥P作为一个聚合密钥或单一密钥的状态永远不会被透露,因为所有的P2TR输出都是彼此相似的,这样将破坏许多链分析启发式方法,增强用户的隐私。

1.其他支付方式

  • P2PKH:Pay-to-Public-Key-Hash(P2PKH)是一种ScriptPubKey,它将比特币锁定在一个公钥的哈希(比特币地址)上。例如,Alice想在P2PKH交易中向Bob发送1个BTC,Bob向Alice提供他钱包中的一个地址,然后Bob的地址会被包括在交易中。当Bob试图花费他收到的比特币时,他必须用对应于公钥的私钥来签署交易,公钥的哈希值与Alice交易中提供的哈希值一致。

  • P2WPKH:Pay-to-Witness-Public-Key-Hash (P2WPKH) 是一种 ScriptPubKey,用于将比特币锁定到 SegWit 地址。 P2WPKH 交易在大多数方面类似于 P2PKH 交易;它仍然将比特币锁定到公钥的哈希值。主要区别在于 P2WPKH 使用 SegWit。这意味着所有输入的 ScriptSig(解锁比特币的脚本)被移出交易主体并进入见证部分,并称为脚本见证。这些数据仍然记录在区块链上,但数据产生的费用会低于常规数据,使得 SegWit 交易比常规交易便宜。

  • P2SH:Pay-to-Script-Hash (P2SH) 是一种 ScriptPubKey, 主要用于多重签名钱包,制作输出脚本逻辑,在接受交易之前检查多重签名。例如,如果 Alice 在 P2SH 交易中向 Bob 发送 1 BTC,她会将花费比特币所需脚本的哈希值包含在交易中。此脚本可能需要 Bob 的私钥和/或许多其他人的签名。当 Bob 想要花费他从 Alice 那里收到的比特币时,他会重建 Alice 用来发送比特币的脚本哈希,并使用脚本所需的任何私钥对交易进行签名。P2SH 非常灵活,因为它允许用户构建任意脚本。此外,交易的发送者不需要知道他们发送到什么脚本类型。在上面的示例中,Bob 可以线下构建他想要的脚本,并且只向 Alice 发送该脚本的哈希值,从而为 Bob 保留更多隐私。

P2WSH:Pay-to-Witness-Script-Hash (P2WSH) 是一种在大多数方面类似于 P2SH 交易的交易类型,除了它使用 SegWit。与 P2SH 交易一样,P2WSH 交易将比特币锁定到脚本的哈希值。为了花费这个比特币,花费者必须出示称为 RedeemScript 的脚本和任何必需的签名。在技术层面上,P2WSH 实际上描述了用于将比特币锁定到 SegWit 脚本哈希的 ScriptPubKey。

2.P2TR优点

通过比较不同类型的签名大小,可以看出在单一签名上使用P2TR是要比同等的P2WPKH要大一点的,但仔细观察会发现,对单一签名的钱包用户和整个网络来说,使用P2TR有很多好处:

DappLink

  • 花费更便宜:在投入层面上,花费一个单一签名的P2TR UTXO比花费一个P2WPKH UTXO要少15%左右。像上表这样过于简单的分析隐藏了一个细节,即花费者不能选择他们被要求支付的地址,所以如果你留在P2WPKH上,而其他人都升级到P2TR,你的2进2出交易的实际典型大小将是232.5vbytes,而所有P2TR交易仍然只有211.5vbytes。

  • 隐私性:虽然早期采用者改用新的脚本格式时,会失去一些隐私,但改用taproot的用户也会立即得到隐私性的提升。你的交易将能够看起来与从事新的LN通道、更有效的DLCs、安全的多重签名、各种巧妙的钱包备份恢复方案或其他一百种开创性发展的人没有区别。现在使用P2TR进行单签名,也允许你的钱包在以后升级到多签名、tapscripts、LN支持或其他功能,而不影响你现有用户的隐私。无论是旧版本还是新版本的软件收到 UTXO 都没有关系——两个 UTXO 在链上看起来都是一样的。

  • 对硬件签名设备来说更方便:自重新发现费用超额支付攻击以来,一些硬件签署设备拒绝签署交易,除非该交易中花费的每个UTXO都有元数据,其中包含产生该UTXO的整个交易的重要部分的副本。而Taproot 消除了费用超额支付攻击的潜在漏洞,因此可以显着提高硬件签名者的性能。

  • 更多的可预测性:P2PKH和P2WPKH UTXO的ECDSA签名可以有不同的大小,由于钱包需要在创建签名之前选择交易的费率,大多数钱包只是假设最坏情况下的签名大小,因此接受较小的签名时将略微多付一些费用。而对于P2TR,签名的大小是事先知道的,允许钱包可以选择一个精确的feerate。

  • 帮助完整的节点:比特币系统的整体安全性取决于大部分比特币用户使用自己的节点验证每笔确认的交易,也包括验证您钱包创建的交易。Taproot的schnorr签名可以有效地进行批量验证,在同步区块的过程中,节点验证签名时需要消耗的CPU周期减少了约1/2。就算你拒绝了上述的所有优点,也要考虑一下使用taproot去帮助运行完整节点的人。 支持P2TR

对于已经支持接收和花费v0 segwit P2WPKH输出的钱包来说,升级到v1 segwit P2TR进行单一签名应该很容易,以下是主要的步骤:

  • 使用新的BIP32密钥推导路径:强烈建议为P2TR公钥使用一个新的推导路径(例如由BIP86定义的),如果你在ECDSA和schnorr签名中使用相同的密钥,可能会被攻击。
  • 通过哈希值来调整你的公钥:虽然技术上不需要单签名,特别是当你的所有密钥都来自随机选择的BIP32种子时,BIP341建议将你的密钥提交到一个不可消耗的scripthash树。这就像使用椭圆曲线加法运算一样简单,将你的公钥与该密钥的哈希值的曲线点相加。遵守这个建议的好处就是如果你以后要增加对无脚本多签名的支持,或者增加对tr()描述符的支持,你将能够使用同样的代码。
  • 创建你的地址并对其进行监控:使用bech32m来创建你的地址。支付将被发送到scriptPubKey OP_1 <tweaked_pubkey>。你可以使用用于扫描 v0 隔离见证地址(如 P2WPKH)的任何方法来扫描支付脚本的交易。
  • 创建一个支出交易:taproot的所有非见证字段都和P2WPKH的一样,所以你不需要担心交易序列化的变化。
  • 创建一个签名信息:这是对支出交易的数据的承诺。大部分数据与你为P2WPKH交易所签署的数据相同,但字段的顺序被改变,还有一些额外的东西被签署。实现这一点只是一个序列化和散列各种数据的问题,所以编写代码应该很容易。
  • 签署签名信息的哈希值:现在已经有许多不同的方法用来创建Schnorr签名了。因此当前最好的方法不是 "推出你自己的方法",而是使用你信任的、经过严格审查的库中的功能。但是,如果你由于某种原因不能这样做,BIP340提供了一种算法,如果你已经有了制作ECDSA签名的基础,那么这种算法应该很容易实现。当你有了你的签名,把它放在输入的见证数据中,然后发送你的支出交易。

3.总结

​ Pay-to-Taproot (P2TR)输出是版本为 1 的SegWit 输出,以后所有的 Taproot 交易都是 SegWit 交易,因此对于开发者,优先尝试一下P2TR是必要的。在taproot在709,632区块激活之前,你就可以使用testnet、公共默认标志或Bitcoin Core的私有regtest模式测试你的代码。


第四题:简述比特币的 POW 共识算法


第五题:比特币有哪些分叉链,产生的原因是什么


第六题:简述 BRC20 的原理


第七题:请说明一下什么是 RGB 协议


第八题:举例说明比特币脚本编程的过程


第九题:Taproot 是如何进行隐私保护的


比特币网络当前的隐私问题

在比特币网络中,个人的交易记录或是商家的现金流可以被任何人追踪到。进一步来说,对于比特币网络常见的多重签名交易类型,用于合作完成一笔交易,但是在现行的比特网络中,当交易输出满足执行解锁条件时,它就会显示整个脚本以及它所包含的所有数据,网络参与者可以通过使用脚本的初始哈希值,在区块链上轻松审计。这些问题的出现是因为比特币的设计本身没有考虑到这一层次的隐私保护,而隐私保护是区块链现在亟待解决的问题。

Schnorr聚合签名保护多方的参与

作为比特币网络的签名算法

ECDSA的全称是椭圆曲线数字签名算法。它在比特币中的作用我们的并不陌生,我们在比特币网络中的每一次签名都用到了 ECDSA 技术。比如说,用户A想发送一笔交易将比特币转账给用户B,必须要让矿工确认只有用户A拥有该UTXO的私钥,即拥有这笔资产的处置权。因此用户A需要用 ECDSA 生成一个独一无二且无法被修改的数字签名,以证明其拥有私钥,同时确认交易部分的具体金额。自比特币诞生以来,该算法很好地胜任了这份生成签名的关键性工作,维持了比特币网络的安全,但是ECDSA缺乏正式的安全证明,并依赖于额外的的假设。Schnorr和ECDSA同样基于离散对数问题,但是Schnorr签名算法有一个正式的数学证明能够证明其安全性,且用到了更少的假设,因此,从安全性角度考虑,Schnorr签名算法接替ECDSA算法也就不足为奇了。

支持聚合签名,实现隐私保护

the-web3

此外,Schnorr最大的优点在于实现了聚合签名,因为Schnorr具备线性特征,这就允许多个用户的公钥 通过线性计算聚合成一个公钥,并能生成与之对应的聚合签名。聚合意味着合并为一个,因此味着当多方参与时,Schnorr聚合签名可以将多个签名数据压缩合并成单个聚合签名了,验证者通过所有签名相关的数据和公钥组成的列表对单个聚合签名进行验证,若验证通过,其效果等同于对所有相关签名进行独立验证且全部通过。

以2-3多签为例,⽬前⽐特币多签的锁定脚本需要3个公钥地址,这部分会被压缩为脚本,所以升级之后⼤⼩⽆变化,但是解锁脚本需要2个公钥与2个签名,在升级为Schnorr之后,只需要⼀个"公钥和"与"签名和"。对于更通⽤的n-m多签,⽬前⽐特币多签的解锁脚本需要n个公钥与n个签名,Schnorr签名依然只需要⼀个"公钥和"与⼀个"签名和”。也就是说签名⼈越多,Schnorr签名的空间利⽤率越⾼。

将多个参与者的签名聚合成一个签名,这使得多签名交易看起来像是常规的P2PKH交易,保护了多重签名参与者的隐私。对比之下,ECDSA 本身是不支持多重签名,比特币现在是通过 P2SH 脚本来处理,但是 P2SH 类的脚本会向网络暴露多签交易的存在并披露所有的签名者。因此,使用 Schnorr 签名,增强交易的隐私性,并节省解锁脚本内因多签带来的空间占用,节约宝贵的链上空间,实现变相扩容。

MAST对交易脚本的隐私保护

MAST

MAST(Merkle Abstract Syntax Tree)由抽象语法树和Merkle树发展而来,AST背后的技术允许我们将一个脚本分割成互斥的子集,而merkle树允许我们在不披露整个脚本的情况下验证单独的脚本子集属于一个完整的脚本。

MAST使用Merkle树对脚本的互斥分支进行编码,这使复杂脚本条件可以通过隐藏未执行的分支脚本来提高隐私。具体表现为,用户支出时,只需披露相关脚本以及从该脚本通向默克树根的路径,用一个默克尔证明就能为执行的脚本提供证明。

op_code

以上面Alice的财产处理脚本为例子,上面指定的脚本不仅包括Alice的公钥(需要验证私钥的签名),还包括Bob和Charlie的公钥和一些条件逻辑,如超时。在当前的BTC网络中,上述的所有数据和脚本被花费都都会记录在链上,因此每个人都可以跟踪到这笔UTXO的所有信息,这对于Alice、Bob、Charlie的隐私来说是不好的消息。

引入MAST后,可以看到MAST树对该脚本的表示如下。

mast-eg

将其分解为两个子脚本,一个脚本是Alice能够随时花费这笔比特币,另一个脚本是三个月后Alice的比特币还没有使用完,Bob和Charlie就可以考虑如何处理这笔比特币了。在实际情况中,只会选择一个分支进行执行,而通过披露的单个分支,无法确定Alice其他的子脚本有做什么动作,从而保护了Alice的隐私。

Taproot升级下的用户的隐私

Taproot本身是一次软分叉升级,在比特币客户端升级后还会兼容老的客户端,这对于比特币本身的发展和社区的凝聚都是强有力的。Taproot通过隐藏交易的全部脚本,同时使复杂交易与其他交易难以区分,增强了比特币网络参与者的隐私性。对不使用复杂交易脚本的普通用户来说,这次Taproot升级是接近无感知的;但对开发者来说,钱包和服务必须升级对应的功能。随着越来越多的用户利用 Taproot 的功能,其对效率和隐私的积极影响被放大。

总言之,相较于现行的比特币网络,区块链分析能够对单个地址进行追踪,taproot为比特币网络纳入了一定的隐私功能,用户的隐私得到保护,也会惠及比特币本身,促进比特币网络的发展,为比特币的未来带来更多可能性。


第十题:简述 Schnorr盲签名

Schnorr盲签名方案

顾名思义,Schnorr 盲签名是签名者不知道他们签署了什么的签名。 可能很难想象这有什么用处,但在处理不经意服务器(Oblivious Server)时,它是一个很好的工具,而这在比特币和整个互联网的未来发挥着重要作用。

不经意服务器指的是一些支持可信计算或数据存储的服务器,用户可能会对其服务进行付费,但服务器却不需要知道它操作的所有信息,这类信息包括用户的身份、哪些方正在相互交互、正在存储哪些数据、正在执行的什么计算等等内容,因为这个过程是不经意的。一个不经意的服务器应该是一个可靠的计算服务,除了计算什么都不做。

将这个场景迁移到比特币网络中,如果采用盲签名,节点只负责运算,而无法知晓正在计算的内容是什么,最终节点打包的区块并不会透露用户的任何隐私,这为用户的匿名性提供了极大保护。用户只需为节点(矿工)支付交易的手续费,就能享受比特币网络提供的隐私性和安全性。

Schnorr盲签名方案有四个步骤:

  • 签名者提供一个随机数

  • 接收者提出一个使用随机数构造的盲挑战(它不显示有关签名内容的信息)

  • 签名者使用步骤 1 中的随机数提供此挑战的正常 schnorr 签名

  • 接收者解开这个签名的盲部分,从而产生一个正常的、有效的 Schnorr 签名,它看起来与签名者提供的签名完全无关,因为 R 和 s 值都由随机数调整。

Schnorr盲签名是如何工作的

在创建盲签名的过程中,具有公钥 X 的签名者和接收者之间的通信类似于Schnorr 的签名协议:

  1. 签名者生成一个随机的 k 并将随机数 R = k*G 发送给接收者。
  2. 接收者响应一个挑战 c
  3. 签名者回复生成的盲签名 s = k + c*x,其中 x 是签名者的私钥。

在正常的 Schnorr 协议中,接收者旨在选择 c 作为他们想要签名的某些消息 m 的哈希 H(X, R, m)。 但是我们使用盲签名的目标是允许接收者以某种方式调整 R 和 s 以获得签名 (R', s'),其中调整值是随机数,因此该签名看起来与原始的 (R, s) 完全无关。

​ 因此,如果我们想完成这个方案,最直接的做法就是让接收者生成随机数 αt,并让 X' = X + t*G, R' = R + α*G, X'和R'是调整后的公钥和随机数。因此它们生成的挑战将是 c = H(X', R', m),生成的盲签名为 s = k + H(X',R',m) * x ,然后需要调整为有效 schnorr 签名。

s'

这样,我们就最终得到了使用密钥 X'签署的消息 m 的有效 Schnorr 签名 (R',s')

然而,这个方案有一个致命的缺陷。 如果签名者试图查看它已签署的内容(例如通过查看比特币交易的所有签名)并且遇到使用公钥 X' 签署消息 m得到的签名 (R', s') ,它将无法识别这些值中的任何一个,这看似达到了匿名的目的 ,但它将能够计算 H(X', R', m) 并将该值与它在步骤 2 中收到的挑战进行比较,这破坏了签名者的匿名性。

为了解决这个问题,可以生成一个新的随机数β ,并用它来调整挑战 c = H(X', R', m) + β,调整后的签名就变成了

s''

并且,我们必须对随机数添加额外的调整以保持一致,调整后得到 R'=R + α∗G + β∗X。现在得到最终的盲签名 (R', s'),其中所有这些值对于签名者来说都是随机的,并且挑战哈希也是随机的。

Schnorr盲签名的安全性

Schnorr 盲签名方案对于所提出的各种攻击来说,实际上并不安全,只是规定签名者在很小一段时间内中止和重试,才能确保使其安全(但也会导致不太有效的签名方案)。正因为如此,通常只有在需要Schnorr签名时使用 Schnorr 盲签名才是有意义的(例如,如果被签名的事物是未来的比特币交易)。对于盲签名的大多数链下用例,使用其他盲签名方案可能更有意义。 如BIP340提及的,确切地说,Schnorr 签名承诺了一个非常简单的盲签名方案,但它是不安全的,因为它容易受到 Wagner 的攻击。一种已知的缓解措施是让签名者以一定的概率中止签名会话,并且可以在非标准密码假设下证明由此产生的方案是安全的。

盲CoinSwap服务器

盲签名的一个有趣用例是 CoinSwap 服务器,CoinSwap 是一对不可链接的交易,通常有两方以原子方式相互支付几乎相等的金额。使用盲签名,可以有一个盲 CoinSwap 服务,用户可以支付少量费用与服务器执行 CoinSwap,而服务器无法跟踪哪个付款对应哪个收款。

就像常规 Schnorr 签名一样,盲签名支持预先提交的随机数方案。具体来说,一旦服务器给出了它的随机数,并且客户端生成了它的调整,客户端就能够计算 s*G,其中 s 来自已知消息的盲签名,这可以实现这些签名的原子购买,这是通过使用 s*G 作为适配器签名中的适配器点来实现的。该签名将用户的付款签署给服