主页 > imtoken钱包官网版最新 > 1、比特币中的UTXO模型是什么?

1、比特币中的UTXO模型是什么?

imtoken钱包官网版最新 2023-04-01 07:50:45

本期漏洞主题为比特币漏洞CVE-2010-5141,可以让攻击者窃取任何人的比特币,危害非常严重。 好在这个漏洞没有被利用,修复速度极快。 该漏洞与比特币脚本引擎相关,对公链开发者具有参考意义; 从目前市面上的公链来看,大多都内置了虚拟机或者脚本引擎来打造DApp生态。 这也是区块链的主要趋势之一。

1、比特币中的UTXO模型是什么?

温馨提示:该漏洞的代码片段会涉及到一些UTXO的相关知识和概念,所以在对漏洞进行理论分析之前,您需要了解这些知识点。 已经知道的可以直接跳过。

. 账户模型和 UTXO 模型

在看UTXO模型之前,先说说普通账户模型。 什么是客户模型? 模型的简单数据结构可以理解为“账户=余额”,每个账户对应一个余额。 例如A账户向B账户转账200,在账户模型中,只需要A-200,然后B-200即可完成转账操作; 目前大部分软件都采用账户模型,如银行系统、以太坊等。

比特币采用自己开发的 UTXO 模型。 UTXO中没有“account=balance”这样的数据结构,那么如何转账呢?

二。 比特币如何操作转账[X] [X] 以上面A到B的转账为例。 在 UTXO 中完成此转账需要以下操作:

1、找到账户A下200的余额来源,即找到交易x

2、其中A收到200,以交易X为输入,以交易Y向B转200为输出,X对应Y,X和Y的转账金额必须相等

3.交易x被标记为过期,交易Y被标记为未过期

两笔交易的转账金额必须相等。 简单的解释就是你只能转出你收到的东西,这就是它的实际情况。

但是,如果我只需要将其中的一部分转让给其他人怎么办? 答案是只转一部分给他人,用另外一个号码转给自己。

. 引用两张网上的图文:

帐户模型

图片1

Coir 雨衣 editor 2022

UTXO模型

在本文中,比特币为什么采用UTXO模型不是重点,我们只能了解UTXO的原理。

图片2

二。 比特币脚本引擎比特币脚本是非图灵完备的。 比特币使用自己定义的脚本进行交易和其他操作,这为比特币提供了有限的灵活性。 实现简单的功能,如多重签名、冻结资金等。但仅此而已。 比特币之所以这样做,是为了牺牲一定的完整性来保证安全性。 比特币脚本的原理是先定义一堆操作码,然后脚本引擎根据栈一个一个地执行每一个操作码。 堆栈很好理解。 队列是先进先出,而栈正好相反。 这是先进先出的。 一个元素被压入栈后,它将是第一个被弹出的元素。 在早期版本的比特币中发送标准转账(pay-to-pubKey)交易需要脚本签名(scriptSig)和公钥验证脚本(scriptPubKey)。 具体处理流程如下:

先填写要执行的脚本,然后签名(sig)然后操作码OP_CHECKSIG会验证签名等,如果验证通过则将true压入栈,否则将false压入栈。

三。 CVE-2010-5141漏洞分析

图片3

了解了以上知识后,就可以开始分析CVE-2010-5141漏洞了。 作者下载了易受攻击的版本0.3.3。 下载地址在github的比特币仓库。 找到释放。 script.cpp 代码片段 VerifySignature 函数:

每笔交易都会调用VerifySignature函数执行脚本并验证签名,然后标记交易是否已经花费。

首先,txFrom 参数是最后一笔交易,txTo 是正在处理的交易。 如果你了解上一章讲解的UTXO模型,到这里就不难理解了。 看1125行代码,调用EvalScript函数,第一个参数是txin.scriptSig(包括签名信息)来分隔opcode OP_CODESEPARATOR? txout.scriptPunKey(包括公钥信息和OP_CHECKSIG指令),这些是EvalScript函数要执行的脚本,后面的参数可以暂时忽略。 只要EvalScript函数返回true,这个验证签名就会通过。 EvalScript 函数如何返回 true?

4

首先栈不能为空,然后强制bool后栈顶必须为true。 作者简单的解释就是一定要有栈顶,而且这个值不能为0。

然后看关键的OP_CHECKSIG操作码

1

(注:由于操作码太多,本文重点介绍OP_CHECKSIG操作码)上面的代码并不难理解。 调用 Checksig 函数对签名进行校验,返回给 FSuccess 变量。 如果为真,请按一个。 如果操作码是 OP_CHECKSIGVERIFY 而不是 OP_CHECKSIG,则让 vchTrue 弹出堆栈并开始执行以下操作码。 按照OP_CHECKSIG的正常逻辑,如果签名验证不成功,栈顶会留下一个vchFalse。 虽然栈不为空,栈顶的值为0,但还是会返回false。

2

回到前面的代码,EvalScript函数执行的脚本主要由以下变量组成:

1. txin.scriptSig

2. OP_CODESEPARATOR

3.输出.scriptpubkey

第一个签名信息是可控的,第二个只是一个分隔符,会被删除比特币会被盗取吗,第三个是不可控的,因为它来自上一笔交易。

第一个变量是可控的,它是作为脚本执行的,所以这个变量既可以是签名信息,也可以是操作码,比较容易处理。 需要在下面引用一个神奇的操作码吗? OP_PUSHDATA4,让我们看看比特币0.3.3是如何处理这个操作码的:

先获取opcode。如果opcode的值小于等于OP_PUSHDATA4的值,则将vchPushValue压入栈中,然后再执行GetOp函数

. 查看源码,发现OP_PUSHDATA4指令定义为78,所以当函数遇到OP_PUSHDATA4时,指针会进一步移动78^4=82位比特币会被盗取吗,其中78位数据会被压入栈中。 所以只要在txin.scriptSig中注入一个OP_PUSHDATA4操作码,后面的公钥信息和OP_CHECKSIG指令就会被“吃掉”,作为参数入栈。 当指针到达末尾时,做最后的判断:

1.堆栈是否为空?而不是

图片4

2. 栈顶元素是否为0?否

图片5

xiaoyi.com小编2022,所以EvalScript函数在满足条件的时候返回true,然后VerifySignature函数也返回true。 由于绕过了签名验证,其他人的比特币就可以随意花掉。

四。 CVE-2010-5141漏洞修复方案

笔者下载了比特币0.3.8版本,直接阅读关键部分代码

修复方案也很明确。 不管你写什么脚本,scriptSig和scriptPubkey都是分开执行的。

写在最后:

由于比特币漏洞分析是从第一篇DVP漏洞专题开始连载的,目前的素材是2010年的,目前的漏洞分析主要有以下难点:

1.关于漏洞的信息非常少。 大多数漏洞只有一个CVE编号和简介,不查阅大量资料无从下手。

3

2、环境搭建困难,比如编译、私链搭建(早期的比特币甚至没有私链的概念)等,比特币早期源码编译需要的很多依赖已经不再维护和离线。 由于这些原因,笔者只进行了理论研究,并未进行实践验证。 如果我错了,请纠正我。5。 参考链接。 堆栈交换。 com/questions/37403/which-release-fixed-CVE-2010-5141-attacker-can consume-any-coins