主页 > imtoken钱包正版 > 比特币钱包介绍
比特币钱包介绍
比特币钱包涉及钱包程序和钱包文件。 钱包程序创建公钥以接受比特币 (satoshis) 付款,并使用相应的私钥来花费比特币。 钱包文件保存着钱包程序相关的私钥和其他交易信息(可选)。
钱包程序
允许接受和支付比特币是钱包软件的唯一功能,但一个特定的钱包程序不需要两者兼顾,两个钱包程序可以协同工作,一个程序分发公钥接收比特币,一个程序进行交易签名以支付对于那些比特币。
钱包程序还需要与点对点网络交互以从区块链获取信息并广播新交易。 当然,分发公钥和签署交易的过程不需要与对等网络本身进行交互。
因此,钱包系统具有三个必要但独立的部分:公钥分发程序、签名程序和联网程序。
注意:这是公钥分发的常见情况。 在某些情况下,P2PKH 和 P2SH 的哈希值将被分发而不是公钥的分发,而实际的公钥只有在他们控制的输出被支付时才会被分发。
上文和下文提到的输出通常是指未花费的交易输出。 简称UTXO,即比特币。
全功能钱包 Full-Service Wallets
最简单的钱包是一个执行三个功能的程序:
几乎所有流行的 BTC 钱包现在都是全服务钱包。
Full-Service Wallets的优点是简单易用,单个程序即可完成用户支付和接收比特币的所有工作。
全服务钱包的缺点是它们将私钥存储在可以连接到互联网的设备上。 由于互联网的存在,这样的设备中的私钥很容易被攻击。
签名钱包 签名钱包
私钥可以保存在更安全环境中的单独钱包程序中,以提高安全性。 这些签名钱包与可以与对等网络交互的网络钱包结合使用。
签名钱包通常使用确定性密钥创建,用于创建可以生成子公钥和私钥的父公钥和私钥。
首次运行时,签名钱包会创建父私钥并将相应的公钥传输到联网钱包。
网络钱包使用父公钥派生子公钥,帮助分发它们(可选),监控支付给这些公钥的输出,创建未签名的支付交易,并将未签名的支付交易传输到签名钱包。
通常用户有机会使用签名钱包查看未签名交易的详细信息(尤其是输出的详细信息)。
用户检查步骤(可选)后,签名钱包使用父私钥导出相应的子私钥并签署交易,并将签名的交易发送回联网钱包。
网络钱包将签名的交易广播到点对点网络。
离线钱包 离线钱包
几个全业务钱包也可以作为两个独立的钱包:一个程序实例作为签名钱包(通常称为“离线钱包”),另一个程序实例作为网络钱包(通常称为在线钱包或监控钱包)。 钱包)。
离线钱包在未连接到互联网的设备上运行,可以减少供应。 如果是这种情况,通常由用户处理所有数据传输并使用可移动设备(例如 USB 驱动器)。 用户的工作流程是这样的:
离线钱包的主要优势在于,与全功能钱包相比,它们大大提高了安全性。 只要离线钱包没有被泄露(或有缺陷),用户在签名前会检查所有已支付的交易,即使在线钱包被泄露,用户的比特币也是安全的。
离线钱包的主要缺点是麻烦。 为了获得最大的安全性,用户必须离线操作。 任何时候支付比特币,都必须激活离线设备,用户必须物理地将数据从在线设备复制到离线设备,然后再将数据从离线设备复制回在线设备。
硬件钱包Hardware Wallets
硬件钱包是专门用于签名的钱包设备,一般是由智能卡等安全芯片开发的设备。 它们可以与其他联网设备安全通信,用户不再需要手动传输数据。 硬件钱包的工作流程如下:
仅分发钱包
运行在安全性难以保证的环境(如Web服务器)的钱包程序只能设计为分发公钥,不能有其他功能。 这种简单的钱包设计有两种常见的方法:
这两种方法都不会增加很多开销。
钱包文件 钱包文件
比特币钱包的核心是一组私钥。 这些收藏以数字方式保存在一个文件中,甚至保存在一张纸上。
私钥格式 私钥格式
私钥用于解锁公钥地址对应的比特币。 在比特币中,标准格式的私钥是一个256位的数字,取值范围如下:
0x01 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4140
此范围受比特币使用的 secp256k1 ECDSA 加密标准管辖。
钱包导入格式 (WIF)
为了让私钥的复制不易出错,可以使用钱包导入格式WIF。 WIF 使用 base58Check 对私钥进行编码,这大大降低了复制错误的机会,就像标准的比特币地址一样。
迷你私钥格式 迷你私钥格式
迷你私钥格式是一种将私钥编码在 30 个字符以内的方法,可以将密钥嵌入到更小的物理空间中,例如物理比特币令牌,或者二维码。
上面说的很啰嗦btc钱包服务器,回去整理一下再写。
公钥格式 公钥格式
比特币的ECDSA公钥代表特定椭圆曲线上的一个点,比特币使用secp256k1。 在传统的未压缩形式中,公钥包含一个标识字节、一个 32 字节的 X 坐标和一个 32 字节的 Y 坐标。
下面是一个超级简单的图表,说明了比特币使用的椭圆曲线上的一个点,
曲线上只有两个点共享任意一个X坐标,所以只需要一个bit来表示Y坐标的正负,也就是把Y坐标压缩成1bit,这样就实现了不用更改任何内容 50% 公钥压缩
使用这个压缩后的公钥不会丢失数据,只需要少量的操作就可以重构Y坐标,使用未压缩的公钥。 secp256官方文档描述了未压缩和压缩的公钥,广泛使用的密码算法库一般都支持这两种格式的公钥。
由于它们的易用性,它们减少了区块链空间btc钱包服务器,压缩公钥是比特币核心中的默认设置,也是所有比特币软件的推荐默认设置。
0.6 之前的比特币核心版本使用未压缩的密钥。 这会造成一些并发症。 未压缩密钥和压缩密钥具有不同的散列形式。 所以同一个密钥适用于两个不同的 P2PKH 地址。 这也意味着必须在签名脚本中以正确的格式提交密钥,以匹配先前输出的公钥脚本中的哈希值。
出于这个原因,比特币核心使用几个不同的标识符字节来帮助程序识别应该如何使用密钥:
分层确定性密钥创建
早期比特币客户端中的钱包是一组随机生成的私钥。 用户必须保存这些密钥的副本。 如果密钥丢失,则无法访问相应的钱包,钱包控制的比特币也无法使用。 向上。 比特币有一个避免地址重用的原则。 每个比特币地址只能用于一次交易,因此用户会有大量的私钥需要保存和备份,所以过早解决不是一个好办法。
分层确定性密钥和传输协议大大简化了钱包备份,消除了使用同一个钱包的多个程序之间重复通信的需要,允许创建可以独立操作的子账户,并赋予每个父账户监控或控制其的能力子账户,即使子账户损坏,每个账户也分为完全访问和受限访问两部分,让不受信任的用户或程序可以接收或监控支付,但不能对外支付。
HD协议利用ECDSA公钥创建函数-point(),它取一个大数(私钥)并将其转换为曲线上的一个点(公钥):
point(private_key) == public_key
由于 point() 的工作方式,它可以通过将现有公钥(父公钥)与另一个公钥(通过整数(i)值)组合来创建子公钥。 p 是所有比特币软件使用的全局常量。
point( (parent_private_key + i) % p ) == parent_public_key + point(i)
这意味着两个或多个独立的程序,如果它们就整数序列达成一致,则可以从单个父密钥对创建一系列唯一的子密钥对,而无需额外的通信。 此外,可以在不接触私钥的情况下实现为收款分发新公钥的过程,从而允许公钥分发过程在不安全的环境(网络服务器)上运行。
子公钥也可以通过重复子密钥拆分操作创建自己的子公钥(孙子公钥):
point( (child_private_key + i) % p ) == child_public_key + point(i)
无论是创建子公钥还是更多后代公钥,对所有交易使用可预测的整数序列并不比使用单个公钥好,因为任何知道子公钥的人都可以通过这个父公钥找到所有其他公钥的子-公钥散布的公钥。 相反,使用随机种子来确定生成的整数序列,这样任何没有种子的人都无法看到子公钥之间的关系。
HD 协议使用单个根种子和不可链接的确定性生成的整数来创建子项、孙项和其他进一步的后代密钥。 每个子密钥还通过其父密钥获得一个确定性生成的种子,称为链码,因此违反一个链码不会破坏整个序列层次结构。
HD 密钥散布需要四个输入:
在上图所示的标准形式中,将父链码、父公钥和索引索引输入到单向哈希HMAC-SHA512中,生成确定性生成但看似随机的512位数据。 哈希输出一共512位,右边的256位(低256位)数据作为新的子链码。 将哈希输出的左256位作为整数和父私钥或父公钥的组合(父私钥和哈希输出的高256位在椭圆曲线上做模G运算) 创建子私钥或子公钥密钥:
child_private_key == (parent_private_key + lefthand_hash_output) % G
child_public_key == point( (parent_private_key + lefthand_hash_output) % G )
child_public_key == point(child_private_key) == parent_public_key + point(lefthand_hash_output)
父链码、父公钥和索引索引计算HMAC-SHA512如下:父公钥(256位)和子密钥的索引(32位)级联,公钥在高位索引,并且合并后的字节顺序为Big endian,对合并后的数据进行HMAC-SHA512运算,父链码作为hash key。
可以看出父私钥和代对应的链码可以计算子私钥,然后用point()和子私钥计算子公钥,用子公钥和point( parent chain code)来计算子公钥 这样,不需要私钥,只知道某一代的公钥和对应代的链码,就可以计算出下一代的公钥。
通过指定不同的代际索引,可以使用相同的父键来分散不同的不相关的子键。 子密钥使用子链码重复密钥分散过程以生成未关联的孙密钥。
因为创建子密钥需要密钥和链码,所以密钥和链码一起称为扩展密钥。 扩展私钥和对应的扩展公钥具有相同的链码。 主私钥(最顶层)和主链码由随机数生成。
根种子由123位、256位或512位的随机数生成。 这个根种子,至少有 128 位,是唯一需要用户备份的数据,未来将用于通过特定的钱包和设置来分散所有密钥。
根种子被散列以创建 512 位看似随机的数据,从中创建主私钥和主链码(统称为主扩展密钥)。 主公钥是使用point()从主私钥计算出来的,主公钥和主链码一起被称为主扩展公钥。 主扩展键在功能上等同于其他扩展键,区别仅在于其位于最顶端。
根种子哈希后的512位输出,左256位作为主私钥,右256位作为主链码
强化键
强化扩展密钥修复了普通扩展密钥的潜在问题。 攻击者如果获得了一个公共扩展密钥的父链码和父公钥,就可以暴力获取由该链码派生的所有链码。 如果攻击者还获得了子私钥、孙私钥或下一代私钥,则可以使用链码生成该私钥后代的所有私钥。
更糟糕的是,攻击者可以反转正常的子私钥分散公式,并简单地从子私钥中减去父链码来恢复父私钥,如上文的子和父所示。 这意味着攻击者只要获得扩展公钥及其后代的任何私钥,就可以恢复扩展公钥的私钥及其分发的所有密钥。
因为扩展后的公钥有对应层级的链码,你可以得到这个公钥后代任意一代的公钥,所以只要得到这个公钥后代的私钥,就可以统计上一代私钥的链码,然后通过私钥-链码计算出上一代的私钥,最后计算出公钥和后代的所有密钥。
上面的增强公开结合了索引索引、父链码和父私钥来创建生成子链码和子私钥的数据。 这种公开使得在不知道父私钥的情况下无法创建子公钥。 换句话说,父扩展公钥不能创建强化的子公钥。
加强密钥生成过程,在父私钥前加一个0x00字节,父私钥和索引索引串联,私钥在高位,索引在低位,字节顺序是大端。 对拼接后的数据进行HMAC-SHA512运算,hash key为父链码,父私钥与hash的高256位在椭圆曲线上做加法取模运算生成子私钥,低 256 位是子链码。 如果ECC取模运算的结果为0,则增加索引值,然后重新计算密钥。 子公钥可以从子私钥计算出来。
因此,加固扩展私钥不如普通扩展私钥有用,但是,加固扩展私钥会创建防火墙,从而不会发生多层密钥分散泄漏。 由于强化后的子扩展公钥无法自行生成孙子链码,所以父扩展公钥的公开不能与孙子私钥的公开结合起来创建曾孙扩展私钥。
HD 协议使用不同的索引来指示是生成普通密钥还是强密钥。 来自 0x000x7FFFFFFF 的索引将生成普通键; 来自 0x800000000xFFFFFFFF 的索引将生成增强键。 为了描述方便,很多开发者用'(素数)表示增强键,所以第一个普通键(0x00)为0,第一个增强键(0x80000000)为0'。
(比特币开发者通常使用 ASCII 撇号而不是 unicode 素数符号。)
此压缩描述进一步与斜杠和 m 或 M 前缀组合以指示层次结构和密钥类型。 m代表私钥,M代表公钥。 例如m/0'/0/122'表示普通子密钥的主私钥(index=0)的增强子密钥第123代(index=122)第1代(index=0)Hardened child私钥(按索引)。
符合BIP32 HD协议的钱包只创建主私钥(m)的强化子密钥,防止子密钥泄露和主密钥泄露。 因为主密钥没有普通的子密钥,HD钱包中不会使用主公钥。 所有其他密钥都可以有普通子密钥,因此可以使用相应的普通扩展公钥。
HD 协议还描述了扩展公钥和扩展私钥的序列化格式。 详情请参考BIP32协议。
储存根种子
HD协议中的根种子是128、256或512位的随机数,这些种子需要备份。 为方便起见,可以使用非数字备份方式,如记忆、手抄等。BIP39定义了一种从助记词创建512位根种子的方法。
生成词的数量与使用的熵值有关:
熵位词
128
12
160
15
192
18
224
21
256
二十四
密码可以是任意长度,可以简单地附加到助记词伪句中,助记词和密码将使用2048次HMAC-SHA512运算产生一个看似随机的512位种子。
零钱包
Loose key wallet中文好像叫零型非确定性钱包,也叫Just a Bunch Of Keys (JBOK),是Bitcoin Core客户端的早期钱包形式,已经废弃。 Bitcoin Core 客户端钱包通过伪随机数生成器自动创建 100 个公私密钥对供以后使用。
这些未使用的私钥存储在一个虚拟密钥池(key pool)中。 之前生成的密钥使用完后,会生成新的密钥放入池中,保证池中有100个未使用的密钥。 钥匙。