主页 > imtoken无法提币 > BTC地址及交易原理解析:比特币,谁在掌控? 还是钱包?

BTC地址及交易原理解析:比特币,谁在掌控? 还是钱包?

imtoken无法提币 2023-06-17 05:27:43

如果您使用的是比特币钱包并且无法回答上述三个问题,那么本文适合您。

安比实验室在对数字钱包源代码进行审计时,发现一个名为pywallet的比特币钱包开源库存在严重缺陷。 如果转账到pywallet生成的OmniLayer接收地址,资产将永久丢失。

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

但是,开源库pywallet在生成OmniLayer钱包地址时,错误地把地址前缀颠倒了,导致多个资产被锁定在无效地址!

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

比特币由谁控制_808比特币创始人颜万卫 炮制比特币风险大_比特币转错到比特币现金地址了

文件地址:

#差异-ca3a8be6f2ab4be3bfd69a49f5f4122a

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

1-地址:这是最常见的比特币地址,通常用于普通的转账和支付。 1-地址其实就是公钥Hash的编码。 验证1-address的签名后,即可解锁支付。

3-Address:这个地址是脚本(Script)的哈希地址。 这种地址其实对应的是一个比特币脚本Hash的代码。

bc1-address:bech32编码地址,用于隔离见证交易。

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

请谨慎使用pywallet开源库! !

事实:比特币从未真正实现过转账功能

这出乎很多人的意料,因为比特币的实现是基于UTXO模型的,这与我们直观理解的账户模型不同。 zer0to0ne解释说,事实上,比特币从来没有真正实现过通常意义上的转账功能。 中本聪只是为比特币设计了一系列的比特币脚本操作符和比特币脚本执行器,而所谓的转账过程其实就是模拟了一个比特币脚本的加锁和解锁过程。 这与日常生活中的账本概念(或账户模型)不同。

为了便于理解,我们可以将比特币区块链上的资产交易比作将资产锁在保险箱中,只有持有保险箱钥匙的人(即收款人)才能取出保险箱中的资产进行交易。 例如,Alice 想付给 Bob 一个资产,Alice 把这个资产锁在一个保险箱里,只有 Bob 有保险箱的钥匙,也就是只有 Bob 可以取出这个资产。 如果 Bob 想取出资产,Bob 必须同时花费资产(即锁入另一个保险箱)。 在 Bob 取出资产之前,资产并不真正属于 Bob。 想象一下,如果 Bob 丢失了密钥,将无法再提取资产。 换句话说,当资产还在保险箱里时,它既不属于爱丽丝,也不完全属于鲍勃。 当然,Alice 也可以把资产放在一个任何人都可以打开的保险箱里,也称为 Anyone-Can-Spend 交易。

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

如果收款人是 1-address,我们称这个保险箱为 1-type 保险箱。 对应的密钥必须是指定接收地址对应的私钥。 保险箱开锁的过程就是验证1地址公钥和该公钥对应的数字签名。 这也是我们通常理解的向普通账户地址转账的验证过​​程。

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

回到本节的问题:为什么说比特币从未实现过真正意义上的转账功能。 答案很简单,因为比特币系统中没有账户的概念,账户之间的转账是不可能的。 一个人以后能打开多少个保险箱也是未知数。

通过上面的解释我们可以看出,当pywallet开源库把一个1-address错误识别为3-address时,就像把原来的1-type safe变成了3-type safe,账户持有人仍然持有1 - 打开保险柜的钥匙,那么保险柜自然无法打开。 那么被zer0to0ne误锁的OmniLayer数字资产能否找回呢?

是否可以使用 1 地址键打开 3 保险箱?

zer0to0ne 随后向我们解释了两个重要概念的来龙去脉,P2PKH(Pay to Public Key Hash)和 P2SH(Pay to Script Hash)。 这两个名词代表两种不同类型的比特币交易。

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

P2PKH——中本聪的伟大发明

Pay to Public Key Hash,顾名思义,就是将比特币放入保险箱,钥匙孔就是公钥哈希(Public Key Hash)。 我们看到的最常见的 1-address 本质上是 Public Key Hash 的一种编码。 1-地址生成过程也很简单。 公钥通过Hash160计算得到Public Key Hash,在Public Key Hash的头部加上前缀0x00,在Hash的末尾加上checksum,通过得到1开头的比特币Base58 地址。

Base58(0x00 +

+校验和)

下面看一下P2PKH交易类型的安全构建过程。 以 Alice 向 Bob 发送比特币为例:

付款人 Alice 在构建保险箱时需要设置锁定脚本:

OP_DUP OP_HASH160(Bob 的接收地址中包含的公钥哈希) OP_EQUALVERIFY OP_CHECKSIG

注:这一步我们可以理解为Alice为Bob定制了一个保险箱,将比特币放入保险箱,并用Bob的公钥PubKey Hash锁定。 现在除了持有私钥的 Bob 之外,没有人可以打开这把锁。

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

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

808比特币创始人颜万卫 炮制比特币风险大_比特币由谁控制_比特币转错到比特币现金地址了

(图片来自掌握比特币)

脚本执行流程如图,Bob签署交易后得到的数据(实际包括数据长度信息),真正的scriptSig应该是

,比特币脚本执行器从 PUSH 数据开始。 PUSH操作会读取第一个字节,获取要压入栈的数据的长度信息,然后继续执行比特币脚本,直到执行完毕,查看执行结果。

首先要压入堆栈的是,然后是

入栈,一个DUP操作会在栈顶复制一份

, HASH160 弹出栈顶并计算Hash,将结果压回栈中比特币由谁控制,然后用EQUALVERIFY弹出Hash比较是否相等,相等则返回True,不相等相等,则交易被标记为无效。 这一步公开了公钥,保证了签名者身份的正确性,但是黑客或者矿工可以利用公开的公钥构造新的交易来代替原来的交易,不能保证安全,所以需要进行下一步保证交易不可伪造,此时仍有

并且,执行CHECKSIG会验证数字签名的正确性,确保签名者拥有地址对应的私钥。

除了持有私钥的人之外,没有人可以伪造数字签名。 至此,一笔比特币P2PKH交易已经安全完成。

再解释一下:当Bob要花掉Alice给他的比特币时,Bob只能用正确的钥匙打开Alice留下的保险箱,把钱放到一个为Bob新建的保险箱里。

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

P2SH——后中本聪时代的重大创新

中本聪设计了如此强大的脚本系统,只用它来构建转账交易似乎太浪费了。 让我们尝试用其他指令构造一些特殊的锁定脚本,并使用其他方法来解锁它们。

例如,我们可以构造一个使用哈希原像解锁交易的脚本:

OP_HASH160 OP_EQUAL

这段脚本的意思是:当满足Hash160(Pre-image)==的条件时,脚本才能解锁成功。

我们继续以保险箱为例,并将这种类型的保险箱命名为 3 型保险箱。 现在 Alice 给 Bob 的比特币被锁在一个由上述 Hash160 保护的保险箱里,我们称它为哈希锁。

这种锁还是需要正确的形状才能打开,但是安全性要弱很多。 缺少数字签名机制导致密钥隐藏的密钥信息不会随着 Bob 的新保险箱而改变。 任何矿工都可以在 Bob 出示密钥的那一刻复制出完全相同的密钥,急忙打开 Alice 留给 Bob 的保险箱(Front-running),将币转给另一个人 Eve,这样原本属于 Bob 的比特币比特币会被洗劫一空。

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

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

2. Pre-image 在交易花费时始终作为输入引用,不会出现在交易的输出端。 UTXO 保持精简,手续费的负担可以转嫁给接收方。

既然描述的输出脚本有很多好处,有没有办法让这个交易安全呢? 这就需要说说什么是P2SH。

Bitcoin Core 开发者 Gavin Adresen 提出了一种称为 Pay to Script Hash (P2SH) 的技术。

P2SH的交易输出还是判断Hash160(Script)==