区块链网站|NFTS 比特币地址 谁控制比特币 你吗?还是钱包?—解析—BTC地址与交易原则

谁控制比特币 你吗?还是钱包?—解析—BTC地址与交易原则

广告位

是谁控制了比特币,是你?还是钱包?—BTC地址与交易原理大剖析

比特币地址有以1开头的地址,也有以3开头的地址。你知道这两者的区别吗?

在这种情况下,地址上的比特币会被锁定?

谁拥有比特币的控制权,你?还是你正在用的钱包?

如果你正在使用比特币钱包,却无法回答以上三个问题,那么这篇文章就是为你而写的。

SECBIT实验室在审计数字钱包的源代码时,发现一个名为pywallet的比特币钱包开源库存在严重缺陷。如果你把钱转到pywallet生成的OmniLayer收款地址,会造成资产永久损失。

SECBIT实验室区块链技术专家zer0to0ne表示,OmniLayer协议允许在比特币区块链上发行自定义资产(如USDT)。全层资产交易的本质是比特币交易。比特币交易的代码库有很多,pywallet就是其中之一。它可以方便地构造OmniLayer格式的比特币交易。目前pywallet已经在一些数字钱包软件中使用。

但是开源库pywallet在生成OmniLayer的钱包地址时,错误地把地址的前缀写反了,部分资产被锁定在无效地址!

以下是pywallet相关错误代码截图:

插队:比特币网络上最常见的地址类型有三种:公共公钥地址(1-地址)、脚本哈希地址(3-地址)和隔离见证地址(bc1-地址)。地址类型由地址的前缀来区分。其中,1地址的前缀为0x00,3地址的前缀为0x05。

1-地址:这是最常见的比特币地址,一般用于普通转账收款。1-地址实际上是公钥散列的代码。1-验证地址签名后,可以解锁收据。

3-Address:这个地址是脚本的散列地址。这种地址实际上对应的是一个比特币脚本哈希的代码。

BC1-Address: bech32编码地址,用于隔离见证事务。

开源库pywallet颠倒了地址前缀,错误地将1地址设置为3地址。因此,原本转移到1-地址的资产会被错误地转移到3-地址。当账户持有人以1地址验证即私钥签名的方式取出资产时,区块链网络以3地址执行脚本的方式执行验证,导致用户无法正常取出资产!

真相:比特币从未真正实现过转账功能,这是很多人始料不及的。由于比特币的实现基于UTXO模型,与我们直观的账户模型不同。Zer0to0ne解释说,实际上比特币从未真正实现通常意义上的转账功能。中本聪只是为比特币设计了一系列的比特币脚本操作器和比特币脚本执行器,而所谓的转账过程实际上是模拟了一个比特币脚本锁定和解锁的过程。这与日常生活中的总账(或账户模型)概念不同。

为了便于理解,我们可以将比特币区块链上的资产交易比喻为将资产锁入保险箱,只有持有保险箱钥匙的人(即收款人)才能取出保险箱中的资产进行交易。例如,如果Alice要向Bob支付一项资产,Alice将该资产锁在一个保险箱中,只有Bob拥有保险箱的钥匙,即只有Bob可以取出该资产。如果Bob想要取出资产,那么Bob需要同时花费资产(即,将它们锁在另一个保险箱中)。在鲍勃拿出资产之前,这些资产并不真正属于鲍勃。想象一下,如果Bob丢失了他的钥匙,他就不能取出他的资产。换句话说,当这个资产仍然保存在保险箱中时,它不属于爱丽丝或鲍勃。当然,爱丽丝也可以把她的资产放在一个任何人都可以打开的保险箱里,这也被称为任何人都可以花的交易。

由于比特币区块链上的支付地址不同,保险箱的类型也不同。不同类型的保险箱需要不同类型的钥匙才能打开。付款方为收款方定制一个保险箱,将资产放入保险箱并上锁,然后将保险箱扔在公共场所。有两种方法可以打开保险箱:

如果收款人是1地址,我们称之为1类保险箱。并且对应的密钥必须是对应于指定收集地址的私钥。保险箱解锁的过程就是验证1地址公钥和公钥对应的数字签名,也就是我们通常理解的转账到普通账户地址的验证过程。

如果收款人是3地址,我们称之为3型保险箱。密钥必须是可执行的比特币脚本。打开保险箱的过程是比特币脚本的哈希值对应3-地址,运行脚本后比特币脚本执行器成功返回。也就是说,只有拥有原始脚本并能成功执行的人,才能提取这个保险箱里的资产。

让我们回到这一节的问题:为什么比特币从来没有实现真正的转账功能?答案很简单,因为比特币系统中没有账户的概念,账户之间的转账无从谈起。未来一个人能开多少个保险柜也是未知数。

从上面的解释中我们知道,当pywallet开源库错误地将1地址识别为3地址时,就像是将原来的1型保险箱改造成了3型保险箱,但是账户持有人仍然持有1型保险箱的钥匙来解锁,那么自然是无法打开保险箱的。那么,zer0to0ne发现的错误锁定的OmniLayer数字资产还能追回吗?

可以用1地址的钥匙打开3保险箱吗?Zer0to0ne随后向我们详细解释了两个重要概念P2PKH(付费公钥哈希)和P2SH(付费脚本哈希)的来龙去脉。这两个名词分别代表两种不同类型的比特币交易。

以下是zer0to0ne的精彩技术细节分析。

P2PKH——中本聪的伟大发明,Pay to Public Key Hash,顾名思义就是把比特币放在保险箱里,而keyhole Hash(公钥哈希。我们看到的最常见的1地址本质上是一个公钥散列的代码。1- address的生成过程也很简单。公钥哈希由Hash160获得,前缀0x00加在公钥哈希的头,校验和加在哈希的尾。Base58后,获得以1开头的比特币地址。

Base58(0x00公钥哈希校验和)

我们来看看P2PKH交易类型的安全构建流程。以爱丽丝给鲍勃发送比特币为例:

付款人Alice在构造保险箱时需要设置一个锁脚本:

注:我们可以把这一步理解为爱丽丝为鲍勃定制了一个保险箱,把比特币放进保险箱,用鲍勃的公钥PubKey Hash锁起来。现在这个锁除了持有私钥的Bob,任何人都打不开。

当Bob需要花费Alice给他的比特币时,他需要提供必要的参数:交易签名公钥(技术俚语:scriptSig)来打开保险箱,这样锁脚本执行后就会返回True。这一步通常由钱包自动完成。

我们来看看比特币节点如何验证scriptSig的合法性。

(图片来自掌握比特币)

脚本执行过程如图所示。Bob签署交易后获得的数据(实际上,它还包含数据长度信息)。真正的scriptSig应该是sig len sig pubKey len pubKey。比特币脚本执行器从推送数据开始。推送操作会读取第一个字节,获取要放入堆栈的数据长度信息,然后继续执行比特币脚本,直到最后执行完毕,并检查执行结果。

首先将sig放入栈中,然后将PubK放入栈中。DUP操作将在栈顶复制PubK的副本。HASH160弹出栈顶并计算散列,然后将结果压回栈中。然后用EQUALVERIFY弹出Hash比较是否相等。如果相等,则返回True。如果不相等,它会将事务标记为无效。这一步公开了公钥,保证了签名人身份的正确性。但是黑客或矿工可以通过暴露的公钥构造一个新的交易来代替原来的交易,这不能保证安全性,所以需要下一步来保证交易不能被伪造。此时栈上有PubK和sig。执行CHECKSIG将验证数字签名的正确性,并确保签名者拥有与地址对应的私钥。

除了持有私钥的人之外,任何人都不能伪造签名。至此,一笔比特币P2PKH交易安全完成。

再解释一遍:当鲍勃想要花掉爱丽丝给他的比特币时,鲍勃只能用正确的钥匙打开爱丽丝留给他的保险箱,把钱放进鲍勃新建造的保险箱。

这时,一些聪明的读者会注意到一个细节:如果鲍勃拿出钥匙,区块链的任何一个矿工都能在打开保险箱之前看到钥匙的形状。理论上,他们可以立即复制一把钥匙,打开爱丽丝留给鲍勃的保险箱并花掉(俗称前跑攻击)。你真的能做到吗?显然,中本聪已经考虑到了这个问题。该密钥中的交易签名是Bob发起的交易的完整签名。假设Bob想把Alice建的保险柜里的比特币放到一个新的保险柜里(给Charlie)。这时,Bob给出的密钥包含了Charlie的公钥Hash。虽然矿工可以复制Bob的钥匙,但是这个钥匙已经隐藏了下一个新保险箱的钥匙信息,所以矿工无法使用这个复制的钥匙完成其他动作(数字签名不能被盗用)。

P2SH——后中本聪时代的伟大创新。中本聪设计了如此强大的脚本系统。只构造转账交易似乎太浪费了。我们试着用其他指令构造一些特殊的加锁脚本,用其他方式解锁。

例如,我们可以构建一个使用哈希前映像解锁事务的脚本:

OP_HASH160HashOP_EQUAL

这个脚本的意思是:当满足Hash160(Pre-image)==Hash的条件时,可以成功解锁脚本。

我们继续通过保险箱的例子来解释,将这类保险箱命名为三级保险箱。现在爱丽丝给鲍勃的比特币被锁在一个由上面的Hash160保护的保险箱里。让我们称之为散列锁。

锁仍然需要正确的形状才能打开,但它的安全性要弱得多。由于缺少数字签名机制而被钥匙隐藏的钥匙信息不会随着Bob新建的保险箱而改变。任何一个矿工只要鲍勃一露出来,就可以复制出确切的密钥,并抢着打开爱丽丝留给鲍勃的前跑保险柜,把硬币转移到另一个人伊芙身上,那么原本属于鲍勃的比特币就会被洗劫一空。

虽然这个脚本非常不安全,但是它有两个非常神奇的功能:

1.交易结构的输出足够短,意味着比特币节点维护的UTXO缓存空间会大大减少。

1.前像总是在交易花完的时候作为输入被引用,不会出现在交易的输出端。UTXO保持精简,同时可以把手续费的负担转移给接收方。

既然所描述的输出脚本有很多好处,那么我们有没有办法让这个事务安全呢?有必要说说P2SH是什么。

比特币的核心开发者加文艾德森(Gavin Adresen)提出了一项名为支付脚本哈希(P2SH)的技术。

P2SH的交易输出仍然是判断Hash160(Script)==Script Hash,其中Script是上面提到的前映像,但是判断完成后,又增加了一步:使用比特币脚本执行程序再次运行脚本本身。

比特币开发者为此类交易创建了专门的地址,从3开始(经Base58编码后,0x05变成了0x03)。地址生成规则是:

Base58(0x05脚本哈希校验和)

这使得事情变得有趣。在前P2SH时代,Script只是作为Hash160的原始镜像存在,但一旦P2SH被激活,Script就必须是有意义的、可执行的比特币脚本。

我们可以在脚本中添加数字签名检查指令,或者多重签名检查功能,甚至可以在P2SH的基础上开发智能合约,即使使用强大的比特币脚本,也可以保持交易的简化。并且由于P2SH交易地址中只存储了脚本Hash,所以在交易成功消费之前,没有人能够知道脚本内容,从而保护了隐私。

P2SH于2012年4月1日激活,开启了比特币的P2SH时代。

现在全世界的3级保险柜都升级了,再也不怕钥匙被复制了,因为保险柜的钥匙都会内置芯片。升级后的保险箱不仅可以检查钥匙形状,还可以读取钥匙内置芯片的数据,芯片中的内容会影响钥匙形状。鲍勃做了一个可以验证钥匙芯片中数字签名的保险箱,让爱丽丝把钱放入保险箱并锁好。虽然打开鲍勃保险箱的钥匙的形状可以被复制,但这把钥匙有一个内置芯片,可以包含各种高级约束,以确保钥匙不会被超越权限滥用。检查完保险箱的形状后,会执行钥匙芯片中的程序来检查有效性,只有两次检查都通过,保险箱才能被打开。

被锁的钱还能追回来吗?有可能回到开头的问题。zer0to0ne遇到了钱包误锁资产的意外。你能用1号地址的钥匙打开3号保险箱并保存保险箱里的资产吗?

这个问题可以这样解释:爱丽丝按照鲍勃的要求做了一个3级保险箱,但是这个保险箱被pywallet误修改了。其实Bob的本意是需要一个1级保险箱,因为Bob手里只有1级保险箱的钥匙。

当爱丽丝用3级保险箱给鲍勃转账比特币时,保险箱需要同时检查钥匙形状和钥匙芯片内容。然而,Bob的1级保险箱的钥匙形状是由公钥决定的。误改成3级保险柜后,钥匙形状检查不变,但没有对应的钥匙芯片内容。

鲍勃试图在钥匙芯片中写入公钥,使钥匙形状与锁相匹配,但芯片中的公钥无法被保险箱正确执行,因此鲍勃可能再也无法从保险箱中解锁他的比特币。

一个新的时代即将到来。Eric Lombrozo,Johnson Lau,Pieter Wuille,比特币开放核心的鼻祖,提出了一个新概念,隔离见证。这是一种可以有效缓解比特币区块拥堵的技术,彻底解决交易延展性的问题。

在SegWit升级之前,每把用过的钥匙都插在保险柜里,钥匙占据了一定的体积,使得仓库无法密集堆积这些用过的保险柜。总是需要为大量暴露的钥匙腾出空间。看看能不能缩小钥匙的体积,用足够便宜的材料制作,节约成本。

于是就有了SegWit(简称SegWit),简单的把保险箱的锁拆了,变成一个带远程无线验证的保险箱。用户可以远离保险箱插入钥匙,以远程打开相应的保险箱。

2017年8月24日,SegWit软叉正式启用,结束了矿工与开发者旷日持久的对抗。

为了兼容3级保险箱,比特币开发者使用了一种叫做P2SH-P2WPKH的技术,通过P2SH包装P2WPKH交易,这样P2WPKH交易就可以骗过不支持SegWit的旧节点。还有一种类似于P2SH包装的P2WSH技术(P2SH-P2WSH),这里就不介绍了。

我们先解释一下什么是P2WPKH:

P2WPKH的全称是Pay to Witness公钥哈希。与P2PKH相比,P2WPKH将scriptSig移到了事务之外,节省了占用的块空间。

这个P2SH需要如何构造才能兼容没有及时升级的比特币节点?

Bob首先生成一个P2PKH地址,从该地址解析公钥散列,然后构造一个类似于下面的脚本:

Script=0x0014公钥哈希

然后计算脚本Hash160以获得脚本哈希,并构造一个3地址:

Base58(0x05脚本哈希校验和)

当Alice将硬币锁定到Bob提供的脚本Hash中时,意味着Bob需要提供正确的脚本来解锁。

Bob通过构造一个有效的脚本通过了Hash160检查,也就是成功通过了密钥形状检查,密钥中的程序可以被外管局正确解析执行。

细心的读者应该又发现问题了。但是,这个密钥缺乏相关的安全约束,可以很容易地被复制。(跑在前面的)矿工有机会篡改交易,把硬币转给Eve。

但升级SegWit后,支持SegWit的比特币节点在验证P2SH后会额外验证Bob的签名是否正确。作为独立于事务的安全约束,数字签名不再占用宝贵的块空间。

zer0to0ne:

SegWit为比特币的扩张做出了贡献,但同时也为保持向前兼容付出了一些代价。在原生SegWit事务被广泛采用之前,使用的是令人困惑的P2SH兼容技术。未来如果所有比特币都统一到bc1- address,那么完全可以避免P2SH包裹技术,区块容量可以最大化。

三个问题的回复比特币地址有以1开头的地址和以3开头的地址。你知道这两者的区别吗?

1- address用作P2PKH事务的目标地址,3- address用作P2SH和SegWit事务的目标地址。

在这种情况下,地址上的比特币会被锁定?

假设一个比特币地址是一个3地址。如果世界上没有人能提供一个能被Hash160验证并能有效执行的脚本,这个地址上的比特币就会被锁定。

谁拥有比特币的控制权,你?还是你正在用的钱包?

如果一个比特币地址是1地址,那么该地址上的比特币被锁在1级保险箱中,拥有私钥的用户拥有该地址上的比特币。请注意,这里的‘拥有私钥’有两层意思:(1)自己把私钥记在心里,(2)不为他人所知。

如果一个比特币地址是一个3地址,那么在用户披露“解锁脚本”之前,没有人知道该地址比特币的所有权。钱包几乎接管了比特币的控制权。如果不知道钱包生成的地址对应的脚本,就相当于交出了地址的控制权,即使备份了私钥/助记符。这是祈祷的时候:钱包里没有虫子。

广告位
本文来自网络,不代表区块链网站|NFTS立场,转载请注明出处:https://www.qklwz.com/btb/qianbao/24925.html
上一篇
下一篇

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

返回顶部